diff options
author | isaacs <i@izs.me> | 2013-04-19 10:50:44 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2013-04-19 10:50:44 -0700 |
commit | 50624a50ee484b8a53cd4f1155e4e53f19c803be (patch) | |
tree | 37c4d13efd0b9f615eceaff99ef31dd411da6696 /deps/v8 | |
parent | 90266750617adb1ce1ca4ce43fe48f9b0fa11343 (diff) | |
download | node-new-50624a50ee484b8a53cd4f1155e4e53f19c803be.tar.gz |
V8: Upgrade to 3.18.1
Diffstat (limited to 'deps/v8')
105 files changed, 1048 insertions, 6519 deletions
diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index fe8425f021..10121a1132 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -29,7 +29,6 @@ shell_g /obj /out /test/cctest/cctest.status2 -/test/es5conform/data /test/message/message.status2 /test/mjsunit/mjsunit.status2 /test/mozilla/CHECKED_OUT_VERSION @@ -37,7 +36,6 @@ shell_g /test/mozilla/downloaded_* /test/mozilla/mozilla.status2 /test/preparser/preparser.status2 -/test/sputnik/sputniktests /test/test262/data /test/test262/test262-* /test/test262/test262.status2 diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 70aa73a43b..5f64a3e923 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,12 @@ +2013-04-18: Version 3.18.1 + + Removed SCons related files and deprecated test suite configurations. + + Improved handling of unary plus (issue 2527). + + Performance and stability improvements on all platforms. + + 2013-04-17: Version 3.18.0 Enabled pretenuring of fast literals in high promotion mode. diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct deleted file mode 100644 index 21d1902733..0000000000 --- a/deps/v8/SConstruct +++ /dev/null @@ -1,1612 +0,0 @@ -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import platform -import re -import subprocess -import sys -import os -from os.path import join, dirname, abspath -from types import DictType, StringTypes -root_dir = dirname(File('SConstruct').rfile().abspath) -src_dir = join(root_dir, 'src') -sys.path.insert(0, join(root_dir, 'tools')) -import js2c, utils - -# ARM_TARGET_LIB is the path to the dynamic library to use on the target -# machine if cross-compiling to an arm machine. You will also need to set -# the additional cross-compiling environment variables to the cross compiler. -ARM_TARGET_LIB = os.environ.get('ARM_TARGET_LIB') -if ARM_TARGET_LIB: - ARM_LINK_FLAGS = ['-Wl,-rpath=' + ARM_TARGET_LIB + '/lib:' + - ARM_TARGET_LIB + '/usr/lib', - '-Wl,--dynamic-linker=' + ARM_TARGET_LIB + - '/lib/ld-linux.so.3'] -else: - ARM_LINK_FLAGS = [] - -GCC_EXTRA_CCFLAGS = [] -GCC_DTOA_EXTRA_CCFLAGS = [] - -LIBRARY_FLAGS = { - 'all': { - 'CPPPATH': [src_dir], - 'regexp:interpreted': { - 'CPPDEFINES': ['V8_INTERPRETED_REGEXP'] - }, - 'mode:debug': { - 'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT', 'VERIFY_HEAP'] - }, - 'objectprint:on': { - 'CPPDEFINES': ['OBJECT_PRINT'], - }, - 'debuggersupport:on': { - 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT'], - }, - 'fasttls:off': { - 'CPPDEFINES': ['V8_NO_FAST_TLS'], - }, - }, - 'gcc': { - 'all': { - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - }, - 'visibility:hidden': { - # Use visibility=default to disable this. - 'CXXFLAGS': ['-fvisibility=hidden'] - }, - 'strictaliasing:off': { - 'CCFLAGS': ['-fno-strict-aliasing'] - }, - 'mode:debug': { - 'CCFLAGS': ['-g', '-O0'], - 'CPPDEFINES': ['ENABLE_DISASSEMBLER', 'DEBUG'], - }, - 'mode:release': { - 'CCFLAGS': ['-O3', '-fomit-frame-pointer', '-fdata-sections', - '-ffunction-sections'], - }, - 'os:linux': { - 'CCFLAGS': ['-ansi'] + GCC_EXTRA_CCFLAGS, - 'library:shared': { - 'CPPDEFINES': ['V8_SHARED', 'BUILDING_V8_SHARED'], - 'LIBS': ['pthread'] - } - }, - 'os:macos': { - 'CCFLAGS': ['-ansi', '-mmacosx-version-min=10.4'], - 'library:shared': { - 'CPPDEFINES': ['V8_SHARED', 'BUILDING_V8_SHARED'], - } - }, - 'os:freebsd': { - 'CPPPATH' : [src_dir, '/usr/local/include'], - 'LIBPATH' : ['/usr/local/lib'], - 'CCFLAGS': ['-ansi'], - 'LIBS': ['execinfo'] - }, - 'os:openbsd': { - 'CPPPATH' : [src_dir, '/usr/local/include'], - 'LIBPATH' : ['/usr/local/lib'], - 'CCFLAGS': ['-ansi'], - }, - 'os:solaris': { - # On Solaris, to get isinf, INFINITY, fpclassify and other macros one - # needs to define __C99FEATURES__. - 'CPPDEFINES': ['__C99FEATURES__'], - 'CPPPATH' : [src_dir, '/usr/local/include'], - 'LIBPATH' : ['/usr/local/lib'], - 'CCFLAGS': ['-ansi'], - }, - 'os:netbsd': { - 'CPPPATH' : [src_dir, '/usr/pkg/include'], - 'LIBPATH' : ['/usr/pkg/lib'], - }, - 'os:win32': { - 'CCFLAGS': ['-DWIN32'], - 'CXXFLAGS': ['-DWIN32'], - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'], - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'arch:arm': { - 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'], - 'unalignedaccesses:on' : { - 'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=1'] - }, - 'unalignedaccesses:off' : { - 'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=0'] - }, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'vfp3:on': { - 'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS'] - }, - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1'], - 'vfp3:on': { - 'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS'] - }, - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } - } - }, - 'simulator:arm': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'], - }, - 'arch:mips': { - 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, - 'mips_arch_variant:loongson': { - 'CPPDEFINES': ['_MIPS_ARCH_LOONGSON'] - }, - 'simulator:none': { - 'CCFLAGS': ['-EL'], - 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'mips_arch_variant:loongson': { - 'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'] - } - } - }, - 'simulator:mips': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'], - 'mipsabi:softfloat': { - 'CPPDEFINES': ['__mips_soft_float=1'], - 'fpu:on': { - 'CPPDEFINES' : ['CAN_USE_FPU_INSTRUCTIONS'] - } - }, - 'mipsabi:hardfloat': { - 'CPPDEFINES': ['__mips_hard_float=1', 'CAN_USE_FPU_INSTRUCTIONS'], - } - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], - 'CCFLAGS': ['-m64'], - 'LINKFLAGS': ['-m64'], - }, - 'gdbjit:on': { - 'CPPDEFINES': ['ENABLE_GDB_JIT_INTERFACE'] - }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'] - } - }, - 'msvc': { - 'all': { - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['/GR-', '/Gy'], - 'CPPDEFINES': ['WIN32'], - 'LINKFLAGS': ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'], - 'CCPDBFLAGS': ['/Zi'] - }, - 'verbose:off': { - 'DIALECTFLAGS': ['/nologo'], - 'ARFLAGS': ['/NOLOGO'] - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', '_USE_32BIT_TIME_T'], - 'LINKFLAGS': ['/MACHINE:X86'], - 'ARFLAGS': ['/MACHINE:X86'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], - 'LINKFLAGS': ['/MACHINE:X64'], - 'ARFLAGS': ['/MACHINE:X64'] - }, - 'mode:debug': { - 'CCFLAGS': ['/Od', '/Gm'], - 'CPPDEFINES': ['_DEBUG', 'ENABLE_DISASSEMBLER', 'DEBUG'], - 'LINKFLAGS': ['/DEBUG'], - 'msvcrt:static': { - 'CCFLAGS': ['/MTd'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MDd'] - } - }, - 'mode:release': { - 'CCFLAGS': ['/O2'], - 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'], - 'msvcrt:static': { - 'CCFLAGS': ['/MT'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MD'] - }, - 'msvcltcg:on': { - 'CCFLAGS': ['/GL'], - 'ARFLAGS': ['/LTCG'], - 'pgo:off': { - 'LINKFLAGS': ['/LTCG'], - }, - 'pgo:instrument': { - 'LINKFLAGS': ['/LTCG:PGI'] - }, - 'pgo:optimize': { - 'LINKFLAGS': ['/LTCG:PGO'] - } - } - } - } -} - - -V8_EXTRA_FLAGS = { - 'gcc': { - 'all': { - 'WARNINGFLAGS': ['-Wall', - '-Werror', - '-W', - '-Wno-unused-parameter', - '-Woverloaded-virtual', - '-Wnon-virtual-dtor'] - }, - 'os:win32': { - 'WARNINGFLAGS': ['-pedantic', - '-Wno-long-long', - '-Wno-pedantic-ms-format'], - 'library:shared': { - 'LIBS': ['winmm', 'ws2_32'] - } - }, - 'os:linux': { - 'WARNINGFLAGS': ['-pedantic'], - 'library:shared': { - 'soname:on': { - 'LINKFLAGS': ['-Wl,-soname,${SONAME}'] - } - } - }, - 'os:macos': { - 'WARNINGFLAGS': ['-pedantic'] - }, - 'arch:arm': { - # This is to silence warnings about ABI changes that some versions of the - # CodeSourcery G++ tool chain produce for each occurrence of varargs. - 'WARNINGFLAGS': ['-Wno-abi'] - }, - 'disassembler:on': { - 'CPPDEFINES': ['ENABLE_DISASSEMBLER'] - } - }, - 'msvc': { - 'all': { - 'WARNINGFLAGS': ['/W3', '/WX', '/wd4351', '/wd4355', '/wd4800'] - }, - 'library:shared': { - 'CPPDEFINES': ['BUILDING_V8_SHARED'], - 'LIBS': ['winmm', 'ws2_32'] - }, - 'arch:arm': { - 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'], - # /wd4996 is to silence the warning about sscanf - # used by the arm simulator. - 'WARNINGFLAGS': ['/wd4996'] - }, - 'arch:mips': { - 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, - }, - 'disassembler:on': { - 'CPPDEFINES': ['ENABLE_DISASSEMBLER'] - } - } -} - - -MKSNAPSHOT_EXTRA_FLAGS = { - 'gcc': { - 'os:linux': { - 'LIBS': ['pthread'], - }, - 'os:macos': { - 'LIBS': ['pthread'], - }, - 'os:freebsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:solaris': { - 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], - 'LINKFLAGS': ['-mt'] - }, - 'os:openbsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'], - }, - 'os:netbsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'compress_startup_data:bz2': { - 'os:linux': { - 'LIBS': ['bz2'] - } - }, - }, - 'msvc': { - 'all': { - 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'], - 'LIBS': ['winmm', 'ws2_32'] - } - } -} - - -DTOA_EXTRA_FLAGS = { - 'gcc': { - 'all': { - 'WARNINGFLAGS': ['-Werror', '-Wno-uninitialized'], - 'CCFLAGS': GCC_DTOA_EXTRA_CCFLAGS - } - }, - 'msvc': { - 'all': { - 'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244'] - } - } -} - - -CCTEST_EXTRA_FLAGS = { - 'all': { - 'CPPPATH': [src_dir], - 'library:shared': { - 'CPPDEFINES': ['USING_V8_SHARED'] - }, - }, - 'gcc': { - 'all': { - 'LIBPATH': [abspath('.')], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, - 'os:linux': { - 'LIBS': ['pthread'], - 'CCFLAGS': ['-Wno-unused-but-set-variable'], - }, - 'os:macos': { - 'LIBS': ['pthread'], - }, - 'os:freebsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:solaris': { - 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], - 'LINKFLAGS': ['-mt'] - }, - 'os:openbsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'os:netbsd': { - 'LIBS': ['execinfo', 'pthread'] - }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS - }, - }, - 'msvc': { - 'all': { - 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'], - 'LIBS': ['winmm', 'ws2_32'] - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], - 'LINKFLAGS': ['/STACK:2097152'] - }, - } -} - - -SAMPLE_FLAGS = { - 'all': { - 'CPPPATH': [join(root_dir, 'include')], - 'library:shared': { - 'CPPDEFINES': ['USING_V8_SHARED'] - }, - }, - 'gcc': { - 'all': { - 'LIBPATH': ['.'], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, - 'os:linux': { - 'LIBS': ['pthread'], - }, - 'os:macos': { - 'LIBS': ['pthread'], - }, - 'os:freebsd': { - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:solaris': { - # On Solaris, to get isinf, INFINITY, fpclassify and other macros one - # needs to define __C99FEATURES__. - 'CPPDEFINES': ['__C99FEATURES__'], - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], - 'LINKFLAGS': ['-mt'] - }, - 'os:openbsd': { - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['execinfo', 'pthread'] - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'os:netbsd': { - 'LIBPATH' : ['/usr/pkg/lib'], - 'LIBS': ['execinfo', 'pthread'] - }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1'], - 'vfp3:on': { - 'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS'] - }, - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } - } - }, - 'arch:ia32': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'arch:x64': { - 'CCFLAGS': ['-m64'], - 'LINKFLAGS': ['-m64'] - }, - 'arch:mips': { - 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, - 'mips_arch_variant:loongson': { - 'CPPDEFINES': ['_MIPS_ARCH_LOONGSON'] - }, - 'simulator:none': { - 'CCFLAGS': ['-EL'], - 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'mips_arch_variant:loongson': { - 'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'], - 'fpu:on': { - 'CPPDEFINES' : ['CAN_USE_FPU_INSTRUCTIONS'] - } - } - } - }, - 'simulator:arm': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'simulator:mips': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'mode:release': { - 'CCFLAGS': ['-O2'] - }, - 'mode:debug': { - 'CCFLAGS': ['-g', '-O0'], - 'CPPDEFINES': ['DEBUG'] - }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'], - 'os:linux': { - 'LIBS': ['bz2'] - } - }, - }, - 'msvc': { - 'all': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'verbose:off': { - 'CCFLAGS': ['/nologo'], - 'LINKFLAGS': ['/NOLOGO'] - }, - 'verbose:on': { - 'LINKFLAGS': ['/VERBOSE'] - }, - 'prof:on': { - 'LINKFLAGS': ['/MAP'] - }, - 'mode:release': { - 'CCFLAGS': ['/O2'], - 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'], - 'msvcrt:static': { - 'CCFLAGS': ['/MT'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MD'] - }, - 'msvcltcg:on': { - 'CCFLAGS': ['/GL'], - 'pgo:off': { - 'LINKFLAGS': ['/LTCG'], - }, - }, - 'pgo:instrument': { - 'LINKFLAGS': ['/LTCG:PGI'] - }, - 'pgo:optimize': { - 'LINKFLAGS': ['/LTCG:PGO'] - } - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X86'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152'] - }, - 'mode:debug': { - 'CCFLAGS': ['/Od'], - 'LINKFLAGS': ['/DEBUG'], - 'CPPDEFINES': ['DEBUG'], - 'msvcrt:static': { - 'CCFLAGS': ['/MTd'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MDd'] - } - } - } -} - - -PREPARSER_FLAGS = { - 'all': { - 'CPPPATH': [join(root_dir, 'include'), src_dir], - 'library:shared': { - 'CPPDEFINES': ['USING_V8_SHARED'] - }, - }, - 'gcc': { - 'all': { - 'LIBPATH': ['.'], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } - } - }, - 'arch:ia32': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'arch:x64': { - 'CCFLAGS': ['-m64'], - 'LINKFLAGS': ['-m64'] - }, - 'arch:mips': { - 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, - 'mips_arch_variant:loongson': { - 'CPPDEFINES': ['_MIPS_ARCH_LOONGSON'] - }, - 'simulator:none': { - 'CCFLAGS': ['-EL'], - 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'mips_arch_variant:loongson': { - 'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'] - } - } - }, - 'simulator:arm': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'simulator:mips': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'], - 'mipsabi:softfloat': { - 'CPPDEFINES': ['__mips_soft_float=1'], - }, - 'mipsabi:hardfloat': { - 'CPPDEFINES': ['__mips_hard_float=1'], - } - }, - 'mode:release': { - 'CCFLAGS': ['-O2'] - }, - 'mode:debug': { - 'CCFLAGS': ['-g', '-O0'], - 'CPPDEFINES': ['DEBUG'] - }, - 'os:freebsd': { - 'LIBPATH' : ['/usr/local/lib'], - }, - }, - 'msvc': { - 'all': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'verbose:off': { - 'CCFLAGS': ['/nologo'], - 'LINKFLAGS': ['/NOLOGO'] - }, - 'verbose:on': { - 'LINKFLAGS': ['/VERBOSE'] - }, - 'prof:on': { - 'LINKFLAGS': ['/MAP'] - }, - 'mode:release': { - 'CCFLAGS': ['/O2'], - 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'], - 'msvcrt:static': { - 'CCFLAGS': ['/MT'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MD'] - }, - 'msvcltcg:on': { - 'CCFLAGS': ['/GL'], - 'pgo:off': { - 'LINKFLAGS': ['/LTCG'], - }, - }, - 'pgo:instrument': { - 'LINKFLAGS': ['/LTCG:PGI'] - }, - 'pgo:optimize': { - 'LINKFLAGS': ['/LTCG:PGO'] - } - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X86'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152'] - }, - 'mode:debug': { - 'CCFLAGS': ['/Od'], - 'LINKFLAGS': ['/DEBUG'], - 'CPPDEFINES': ['DEBUG'], - 'msvcrt:static': { - 'CCFLAGS': ['/MTd'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MDd'] - } - } - } -} - - -D8_FLAGS = { - 'all': { - 'library:shared': { - 'CPPDEFINES': ['V8_SHARED'], - 'LIBS': ['v8'], - 'LIBPATH': ['.'] - }, - }, - 'gcc': { - 'all': { - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, - 'console:readline': { - 'LIBS': ['readline'] - }, - 'os:linux': { - 'LIBS': ['pthread'], - }, - 'os:macos': { - 'LIBS': ['pthread'], - }, - 'os:freebsd': { - 'LIBS': ['pthread'], - }, - 'os:solaris': { - 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], - 'LINKFLAGS': ['-mt'] - }, - 'os:openbsd': { - 'LIBS': ['pthread'], - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'], - }, - 'os:netbsd': { - 'LIBS': ['pthread'], - }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS - }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'], - 'os:linux': { - 'LIBS': ['bz2'] - } - } - }, - 'msvc': { - 'all': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'verbose:off': { - 'CCFLAGS': ['/nologo'], - 'LINKFLAGS': ['/NOLOGO'] - }, - 'verbose:on': { - 'LINKFLAGS': ['/VERBOSE'] - }, - 'prof:on': { - 'LINKFLAGS': ['/MAP'] - }, - 'mode:release': { - 'CCFLAGS': ['/O2'], - 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'], - 'msvcrt:static': { - 'CCFLAGS': ['/MT'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MD'] - }, - 'msvcltcg:on': { - 'CCFLAGS': ['/GL'], - 'pgo:off': { - 'LINKFLAGS': ['/LTCG'], - }, - }, - 'pgo:instrument': { - 'LINKFLAGS': ['/LTCG:PGI'] - }, - 'pgo:optimize': { - 'LINKFLAGS': ['/LTCG:PGO'] - } - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X86'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152'] - }, - 'mode:debug': { - 'CCFLAGS': ['/Od'], - 'LINKFLAGS': ['/DEBUG'], - 'CPPDEFINES': ['DEBUG'], - 'msvcrt:static': { - 'CCFLAGS': ['/MTd'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MDd'] - } - } - } -} - - -SUFFIXES = { - 'release': '', - 'debug': '_g' -} - - -def Abort(message): - print message - sys.exit(1) - - -def GuessOS(env): - return utils.GuessOS() - - -def GuessArch(env): - return utils.GuessArchitecture() - - -def GuessToolchain(env): - tools = env['TOOLS'] - if 'gcc' in tools: - return 'gcc' - elif 'msvc' in tools: - return 'msvc' - else: - return None - - -def GuessVisibility(env): - os = env['os'] - toolchain = env['toolchain']; - if (os == 'win32' or os == 'cygwin') and toolchain == 'gcc': - # MinGW / Cygwin can't do it. - return 'default' - elif os == 'solaris': - return 'default' - else: - return 'hidden' - - -def GuessStrictAliasing(env): - # There seems to be a problem with gcc 4.5.x. - # See http://code.google.com/p/v8/issues/detail?id=884 - # It can be worked around by disabling strict aliasing. - toolchain = env['toolchain']; - if toolchain == 'gcc': - env = Environment(tools=['gcc']) - # The gcc version should be available in env['CCVERSION'], - # but when scons detects msvc this value is not set. - version = subprocess.Popen([env['CC'], '-dumpversion'], - stdout=subprocess.PIPE).communicate()[0] - if version.find('4.5') == 0: - return 'off' - return 'default' - - -PLATFORM_OPTIONS = { - 'arch': { - 'values': ['arm', 'ia32', 'x64', 'mips'], - 'guess': GuessArch, - 'help': 'the architecture to build for' - }, - 'os': { - 'values': ['freebsd', 'linux', 'macos', 'win32', 'openbsd', 'solaris', 'cygwin', 'netbsd'], - 'guess': GuessOS, - 'help': 'the os to build for' - }, - 'toolchain': { - 'values': ['gcc', 'msvc'], - 'guess': GuessToolchain, - 'help': 'the toolchain to use' - } -} - -SIMPLE_OPTIONS = { - 'regexp': { - 'values': ['native', 'interpreted'], - 'default': 'native', - 'help': 'Whether to use native or interpreted regexp implementation' - }, - 'snapshot': { - 'values': ['on', 'off', 'nobuild'], - 'default': 'off', - 'help': 'build using snapshots for faster start-up' - }, - 'prof': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'enable profiling of build target' - }, - 'gdbjit': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'enable GDB JIT interface' - }, - 'library': { - 'values': ['static', 'shared'], - 'default': 'static', - 'help': 'the type of library to produce' - }, - 'objectprint': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'enable object printing' - }, - 'profilingsupport': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'enable profiling of JavaScript code' - }, - 'debuggersupport': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'enable debugging of JavaScript code' - }, - 'soname': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'turn on setting soname for Linux shared library' - }, - 'msvcrt': { - 'values': ['static', 'shared'], - 'default': 'static', - 'help': 'the type of Microsoft Visual C++ runtime library to use' - }, - 'msvcltcg': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'use Microsoft Visual C++ link-time code generation' - }, - 'simulator': { - 'values': ['arm', 'mips', 'none'], - 'default': 'none', - 'help': 'build with simulator' - }, - 'unalignedaccesses': { - 'values': ['default', 'on', 'off'], - 'default': 'default', - 'help': 'set whether the ARM target supports unaligned accesses' - }, - 'disassembler': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'enable the disassembler to inspect generated code' - }, - 'fasttls': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'enable fast thread local storage support ' - '(if available on the current architecture/platform)' - }, - 'sourcesignatures': { - 'values': ['MD5', 'timestamp'], - 'default': 'MD5', - 'help': 'set how the build system detects file changes' - }, - 'console': { - 'values': ['dumb', 'readline'], - 'default': 'dumb', - 'help': 'the console to use for the d8 shell' - }, - 'verbose': { - 'values': ['on', 'off'], - 'default': 'off', - 'help': 'more output from compiler and linker' - }, - 'visibility': { - 'values': ['default', 'hidden'], - 'guess': GuessVisibility, - 'help': 'shared library symbol visibility' - }, - 'strictaliasing': { - 'values': ['default', 'off'], - 'guess': GuessStrictAliasing, - 'help': 'assume strict aliasing while optimizing' - }, - 'pgo': { - 'values': ['off', 'instrument', 'optimize'], - 'default': 'off', - 'help': 'select profile guided optimization variant', - }, - 'armeabi': { - 'values': ['hard', 'softfp', 'soft'], - 'default': 'softfp', - 'help': 'generate calling conventiont according to selected ARM EABI variant' - }, - 'mipsabi': { - 'values': ['hardfloat', 'softfloat', 'none'], - 'default': 'hardfloat', - 'help': 'generate calling conventiont according to selected mips ABI' - }, - 'mips_arch_variant': { - 'values': ['mips32r2', 'mips32r1', 'loongson'], - 'default': 'mips32r2', - 'help': 'mips variant' - }, - 'compress_startup_data': { - 'values': ['off', 'bz2'], - 'default': 'off', - 'help': 'compress startup data (snapshot) [Linux only]' - }, - 'vfp3': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'use vfp3 instructions when building the snapshot [Arm only]' - }, - 'fpu': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'use fpu instructions when building the snapshot [MIPS only]' - }, - 'I_know_I_should_build_with_GYP': { - 'values': ['yes', 'no'], - 'default': 'no', - 'help': 'grace period: temporarily override SCons deprecation' - } - -} - -ALL_OPTIONS = dict(PLATFORM_OPTIONS, **SIMPLE_OPTIONS) - - -def AddOptions(options, result): - guess_env = Environment(options=result) - for (name, option) in options.iteritems(): - if 'guess' in option: - # Option has a guess function - guess = option.get('guess') - default = guess(guess_env) - else: - # Option has a fixed default - default = option.get('default') - help = '%s (%s)' % (option.get('help'), ", ".join(option['values'])) - result.Add(name, help, default) - - -def GetOptions(): - result = Options() - result.Add('mode', 'compilation mode (debug, release)', 'release') - result.Add('sample', 'build sample (shell, process, lineprocessor)', '') - result.Add('cache', 'directory to use for scons build cache', '') - result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '') - result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '') - AddOptions(PLATFORM_OPTIONS, result) - AddOptions(SIMPLE_OPTIONS, result) - return result - - -def GetTools(opts): - env = Environment(options=opts) - os = env['os'] - toolchain = env['toolchain'] - if os == 'win32' and toolchain == 'gcc': - return ['mingw'] - elif os == 'win32' and toolchain == 'msvc': - return ['msvc', 'mslink', 'mslib', 'msvs'] - else: - return ['default'] - - -def GetVersionComponents(): - MAJOR_VERSION_PATTERN = re.compile(r"#define\s+MAJOR_VERSION\s+(.*)") - MINOR_VERSION_PATTERN = re.compile(r"#define\s+MINOR_VERSION\s+(.*)") - BUILD_NUMBER_PATTERN = re.compile(r"#define\s+BUILD_NUMBER\s+(.*)") - PATCH_LEVEL_PATTERN = re.compile(r"#define\s+PATCH_LEVEL\s+(.*)") - - patterns = [MAJOR_VERSION_PATTERN, - MINOR_VERSION_PATTERN, - BUILD_NUMBER_PATTERN, - PATCH_LEVEL_PATTERN] - - source = open(join(root_dir, 'src', 'version.cc')).read() - version_components = [] - for pattern in patterns: - match = pattern.search(source) - if match: - version_components.append(match.group(1).strip()) - else: - version_components.append('0') - - return version_components - - -def GetVersion(): - version_components = GetVersionComponents() - - if version_components[len(version_components) - 1] == '0': - version_components.pop() - return '.'.join(version_components) - - -def GetSpecificSONAME(): - SONAME_PATTERN = re.compile(r"#define\s+SONAME\s+\"(.*)\"") - - source = open(join(root_dir, 'src', 'version.cc')).read() - match = SONAME_PATTERN.search(source) - - if match: - return match.group(1).strip() - else: - return '' - - -def SplitList(str): - return [ s for s in str.split(",") if len(s) > 0 ] - - -def IsLegal(env, option, values): - str = env[option] - for s in SplitList(str): - if not s in values: - Abort("Illegal value for option %s '%s'." % (option, s)) - return False - return True - - -def WarnAboutDeprecation(): - print """ - ##################################################################### - # # - # LAST WARNING: Building V8 with SCons is deprecated. # - # # - # This only works because you have overridden the kill switch. # - # # - # MIGRATE TO THE GYP-BASED BUILD NOW! # - # # - # Instructions: http://code.google.com/p/v8/wiki/BuildingWithGYP. # - # # - ##################################################################### - """ - - -def VerifyOptions(env): - if env['I_know_I_should_build_with_GYP'] != 'yes': - Abort("Building V8 with SCons is no longer supported. Please use GYP " - "instead; you can find instructions are at " - "http://code.google.com/p/v8/wiki/BuildingWithGYP.\n\n" - "Quitting.\n\n" - "For a limited grace period, you can specify " - "\"I_know_I_should_build_with_GYP=yes\" to override.") - else: - WarnAboutDeprecation() - import atexit - atexit.register(WarnAboutDeprecation) - - if not IsLegal(env, 'mode', ['debug', 'release']): - return False - if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]): - return False - if not IsLegal(env, 'regexp', ["native", "interpreted"]): - return False - if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on': - Abort("Profiling on windows only supported for static library.") - if env['gdbjit'] == 'on' and ((env['os'] != 'linux' and env['os'] != 'macos') or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')): - Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux/OSX target.") - if env['os'] == 'win32' and env['soname'] == 'on': - Abort("Shared Object soname not applicable for Windows.") - if env['soname'] == 'on' and env['library'] == 'static': - Abort("Shared Object soname not applicable for static library.") - if env['os'] != 'win32' and env['pgo'] != 'off': - Abort("Profile guided optimization only supported on Windows.") - if env['cache'] and not os.path.isdir(env['cache']): - Abort("The specified cache directory does not exist.") - if not (env['arch'] == 'arm' or env['simulator'] == 'arm') and ('unalignedaccesses' in ARGUMENTS): - print env['arch'] - print env['simulator'] - Abort("Option unalignedaccesses only supported for the ARM architecture.") - if env['os'] != 'linux' and env['compress_startup_data'] != 'off': - Abort("Startup data compression is only available on Linux") - for (name, option) in ALL_OPTIONS.iteritems(): - if (not name in env): - message = ("A value for option %s must be specified (%s)." % - (name, ", ".join(option['values']))) - Abort(message) - if not env[name] in option['values']: - message = ("Unknown %s value '%s'. Possible values are (%s)." % - (name, env[name], ", ".join(option['values']))) - Abort(message) - - -class BuildContext(object): - - def __init__(self, options, env_overrides, samples): - self.library_targets = [] - self.mksnapshot_targets = [] - self.cctest_targets = [] - self.sample_targets = [] - self.d8_targets = [] - self.options = options - self.env_overrides = env_overrides - self.samples = samples - self.preparser_targets = [] - self.use_snapshot = (options['snapshot'] != 'off') - self.build_snapshot = (options['snapshot'] == 'on') - self.flags = None - - def AddRelevantFlags(self, initial, flags): - result = initial.copy() - toolchain = self.options['toolchain'] - if toolchain in flags: - self.AppendFlags(result, flags[toolchain].get('all')) - for option in sorted(self.options.keys()): - value = self.options[option] - self.AppendFlags(result, flags[toolchain].get(option + ':' + value)) - self.AppendFlags(result, flags.get('all')) - return result - - def AddRelevantSubFlags(self, options, flags): - self.AppendFlags(options, flags.get('all')) - for option in sorted(self.options.keys()): - value = self.options[option] - self.AppendFlags(options, flags.get(option + ':' + value)) - - def GetRelevantSources(self, source): - result = [] - result += source.get('all', []) - for (name, value) in self.options.iteritems(): - source_value = source.get(name + ':' + value, []) - if type(source_value) == dict: - result += self.GetRelevantSources(source_value) - else: - result += source_value - return sorted(result) - - def AppendFlags(self, options, added): - if not added: - return - for (key, value) in added.iteritems(): - if key.find(':') != -1: - self.AddRelevantSubFlags(options, { key: value }) - else: - if not key in options: - options[key] = value - else: - prefix = options[key] - if isinstance(prefix, StringTypes): prefix = prefix.split() - options[key] = prefix + value - - def ConfigureObject(self, env, input, **kw): - if (kw.has_key('CPPPATH') and env.has_key('CPPPATH')): - kw['CPPPATH'] += env['CPPPATH'] - if self.options['library'] == 'static': - return env.StaticObject(input, **kw) - else: - return env.SharedObject(input, **kw) - - def ApplyEnvOverrides(self, env): - if not self.env_overrides: - return - if type(env['ENV']) == DictType: - env['ENV'].update(**self.env_overrides) - else: - env['ENV'] = self.env_overrides - - -def PostprocessOptions(options, os): - # Adjust architecture if the simulator option has been set - if (options['simulator'] != 'none') and (options['arch'] != options['simulator']): - if 'arch' in ARGUMENTS: - # Print a warning if arch has explicitly been set - print "Warning: forcing architecture to match simulator (%s)" % options['simulator'] - options['arch'] = options['simulator'] - if (options['prof'] != 'off') and (options['profilingsupport'] == 'off'): - # Print a warning if profiling is enabled without profiling support - print "Warning: forcing profilingsupport on when prof is on" - options['profilingsupport'] = 'on' - if os == 'win32' and options['pgo'] != 'off' and options['msvcltcg'] == 'off': - if 'msvcltcg' in ARGUMENTS: - print "Warning: forcing msvcltcg on as it is required for pgo (%s)" % options['pgo'] - options['msvcltcg'] = 'on' - if (options['mipsabi'] != 'none') and (options['arch'] != 'mips') and (options['simulator'] != 'mips'): - options['mipsabi'] = 'none' - - -def ParseEnvOverrides(arg, imports): - # The environment overrides are in the format NAME0:value0,NAME1:value1,... - # The environment imports are in the format NAME0,NAME1,... - overrides = {} - for var in imports.split(','): - if var in os.environ: - overrides[var] = os.environ[var] - for override in arg.split(','): - pos = override.find(':') - if pos == -1: - continue - overrides[override[:pos].strip()] = override[pos+1:].strip() - return overrides - - -def BuildSpecific(env, mode, env_overrides, tools): - options = {'mode': mode} - for option in ALL_OPTIONS: - options[option] = env[option] - PostprocessOptions(options, env['os']) - - context = BuildContext(options, env_overrides, samples=SplitList(env['sample'])) - - # Remove variables which can't be imported from the user's external - # environment into a construction environment. - user_environ = os.environ.copy() - try: - del user_environ['ENV'] - except KeyError: - pass - - library_flags = context.AddRelevantFlags(user_environ, LIBRARY_FLAGS) - v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS) - mksnapshot_flags = context.AddRelevantFlags(library_flags, MKSNAPSHOT_EXTRA_FLAGS) - dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS) - cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS) - sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS) - preparser_flags = context.AddRelevantFlags(user_environ, PREPARSER_FLAGS) - d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS) - - context.flags = { - 'v8': v8_flags, - 'mksnapshot': mksnapshot_flags, - 'dtoa': dtoa_flags, - 'cctest': cctest_flags, - 'sample': sample_flags, - 'd8': d8_flags, - 'preparser': preparser_flags - } - - # Generate library base name. - target_id = mode - suffix = SUFFIXES[target_id] - library_name = 'v8' + suffix - preparser_library_name = 'v8preparser' + suffix - version = GetVersion() - if context.options['soname'] == 'on': - # When building shared object with SONAME version the library name. - library_name += '-' + version - - # Generate library SONAME if required by the build. - if context.options['soname'] == 'on': - soname = GetSpecificSONAME() - if soname == '': - soname = 'lib' + library_name + '.so' - env['SONAME'] = soname - - # Build the object files by invoking SCons recursively. - d8_env = Environment(tools=tools) - d8_env.Replace(**context.flags['d8']) - (object_files, shell_files, mksnapshot, preparser_files) = env.SConscript( - join('src', 'SConscript'), - build_dir=join('obj', target_id), - exports='context tools d8_env', - duplicate=False - ) - - context.mksnapshot_targets.append(mksnapshot) - - # Link the object files into a library. - env.Replace(**context.flags['v8']) - - context.ApplyEnvOverrides(env) - if context.options['library'] == 'static': - library = env.StaticLibrary(library_name, object_files) - preparser_library = env.StaticLibrary(preparser_library_name, - preparser_files) - else: - # There seems to be a glitch in the way scons decides where to put - # PDB files when compiling using MSVC so we specify it manually. - # This should not affect any other platforms. - pdb_name = library_name + '.dll.pdb' - library = env.SharedLibrary(library_name, object_files, PDB=pdb_name) - preparser_pdb_name = preparser_library_name + '.dll.pdb'; - preparser_soname = 'lib' + preparser_library_name + '.so'; - preparser_library = env.SharedLibrary(preparser_library_name, - preparser_files, - PDB=preparser_pdb_name, - SONAME=preparser_soname) - context.library_targets.append(library) - context.library_targets.append(preparser_library) - - context.ApplyEnvOverrides(d8_env) - if context.options['library'] == 'static': - shell = d8_env.Program('d8' + suffix, object_files + shell_files) - else: - shell = d8_env.Program('d8' + suffix, shell_files) - d8_env.Depends(shell, library) - context.d8_targets.append(shell) - - for sample in context.samples: - sample_env = Environment(tools=tools) - sample_env.Replace(**context.flags['sample']) - sample_env.Prepend(LIBS=[library_name]) - context.ApplyEnvOverrides(sample_env) - sample_object = sample_env.SConscript( - join('samples', 'SConscript'), - build_dir=join('obj', 'sample', sample, target_id), - exports='sample context tools', - duplicate=False - ) - sample_name = sample + suffix - sample_program = sample_env.Program(sample_name, sample_object) - sample_env.Depends(sample_program, library) - context.sample_targets.append(sample_program) - - cctest_env = env.Copy() - cctest_env.Prepend(LIBS=[library_name]) - cctest_program = cctest_env.SConscript( - join('test', 'cctest', 'SConscript'), - build_dir=join('obj', 'test', target_id), - exports='context object_files tools', - duplicate=False - ) - context.cctest_targets.append(cctest_program) - - preparser_env = env.Copy() - preparser_env.Replace(**context.flags['preparser']) - preparser_env.Prepend(LIBS=[preparser_library_name]) - context.ApplyEnvOverrides(preparser_env) - preparser_object = preparser_env.SConscript( - join('preparser', 'SConscript'), - build_dir=join('obj', 'preparser', target_id), - exports='context tools', - duplicate=False - ) - preparser_name = join('obj', 'preparser', target_id, 'preparser') - preparser_program = preparser_env.Program(preparser_name, preparser_object); - preparser_env.Depends(preparser_program, preparser_library) - context.preparser_targets.append(preparser_program) - - return context - - -def Build(): - opts = GetOptions() - tools = GetTools(opts) - env = Environment(options=opts, tools=tools) - - Help(opts.GenerateHelpText(env)) - VerifyOptions(env) - env_overrides = ParseEnvOverrides(env['env'], env['importenv']) - - SourceSignatures(env['sourcesignatures']) - - libraries = [] - mksnapshots = [] - cctests = [] - samples = [] - preparsers = [] - d8s = [] - modes = SplitList(env['mode']) - for mode in modes: - context = BuildSpecific(env.Copy(), mode, env_overrides, tools) - libraries += context.library_targets - mksnapshots += context.mksnapshot_targets - cctests += context.cctest_targets - samples += context.sample_targets - preparsers += context.preparser_targets - d8s += context.d8_targets - - env.Alias('library', libraries) - env.Alias('mksnapshot', mksnapshots) - env.Alias('cctests', cctests) - env.Alias('sample', samples) - env.Alias('d8', d8s) - env.Alias('preparser', preparsers) - - if env['sample']: - env.Default('sample') - else: - env.Default('library') - - if env['cache']: - CacheDir(env['cache']) - -# We disable deprecation warnings because we need to be able to use -# env.Copy without getting warnings for compatibility with older -# version of scons. Also, there's a bug in some revisions that -# doesn't allow this flag to be set, so we swallow any exceptions. -# Lovely. -try: - SetOption('warn', 'no-deprecated') -except: - pass - -Build() diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 8028b3eecb..0b1f397268 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -454,6 +454,15 @@ }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \ or OS=="android"', { + 'cflags!': [ + '-O2', + '-Os', + ], + 'cflags': [ + '-fdata-sections', + '-ffunction-sections', + '-O3', + ], 'conditions': [ [ 'gcc_version==44 and clang==0', { 'cflags': [ diff --git a/deps/v8/preparser/SConscript b/deps/v8/preparser/SConscript deleted file mode 100644 index 10b3953193..0000000000 --- a/deps/v8/preparser/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2011 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from os.path import join -Import('context tools') - -def ConfigureObjectFiles(): - env = Environment(tools=tools) - env.Replace(**context.flags['preparser']) - context.ApplyEnvOverrides(env) - return env.Object('preparser-process.cc') - -preparser_object = ConfigureObjectFiles() -Return('preparser_object') diff --git a/deps/v8/samples/SConscript b/deps/v8/samples/SConscript deleted file mode 100644 index 84c48c9047..0000000000 --- a/deps/v8/samples/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2008 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from os.path import join -Import('sample context tools') - -def ConfigureObjectFiles(): - env = Environment(tools=tools) - env.Replace(**context.flags['sample']) - context.ApplyEnvOverrides(env) - return env.Object(sample + '.cc') - -sample_object = ConfigureObjectFiles() -Return('sample_object') diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript deleted file mode 100755 index 772ac4eb2c..0000000000 --- a/deps/v8/src/SConscript +++ /dev/null @@ -1,413 +0,0 @@ -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import sys -from os.path import join, dirname, abspath -root_dir = dirname(File('SConstruct').rfile().abspath) -sys.path.append(join(root_dir, 'tools')) -import js2c -Import('context') -Import('tools') -Import('d8_env') - - -SOURCES = { - 'all': Split(""" - accessors.cc - allocation.cc - api.cc - assembler.cc - ast.cc - atomicops_internals_x86_gcc.cc - bignum-dtoa.cc - bignum.cc - bootstrapper.cc - builtins.cc - cached-powers.cc - checks.cc - circular-queue.cc - code-stubs.cc - codegen.cc - compilation-cache.cc - compiler.cc - contexts.cc - conversions.cc - counters.cc - cpu-profiler.cc - data-flow.cc - date.cc - dateparser.cc - debug-agent.cc - debug.cc - deoptimizer.cc - disassembler.cc - diy-fp.cc - dtoa.cc - elements-kind.cc - elements.cc - execution.cc - extensions/externalize-string-extension.cc - extensions/gc-extension.cc - extensions/statistics-extension.cc - factory.cc - fast-dtoa.cc - fixed-dtoa.cc - flags.cc - frames.cc - full-codegen.cc - func-name-inferrer.cc - gdb-jit.cc - global-handles.cc - handles.cc - heap-profiler.cc - heap-snapshot-generator.cc - heap.cc - hydrogen-instructions.cc - hydrogen.cc - ic.cc - incremental-marking.cc - interface.cc - interpreter-irregexp.cc - isolate.cc - jsregexp.cc - lithium-allocator.cc - lithium.cc - liveedit.cc - log-utils.cc - log.cc - mark-compact.cc - messages.cc - objects-printer.cc - objects-visiting.cc - objects.cc - once.cc - optimizing-compiler-thread.cc - parser.cc - preparse-data.cc - preparser.cc - profile-generator.cc - property.cc - regexp-macro-assembler-irregexp.cc - regexp-macro-assembler.cc - regexp-stack.cc - rewriter.cc - runtime-profiler.cc - runtime.cc - safepoint-table.cc - scanner-character-streams.cc - scanner.cc - scopeinfo.cc - scopes.cc - serialize.cc - snapshot-common.cc - spaces.cc - store-buffer.cc - string-search.cc - string-stream.cc - strtod.cc - stub-cache.cc - token.cc - transitions.cc - type-info.cc - unicode.cc - utils.cc - v8-counters.cc - v8.cc - v8conversions.cc - v8threads.cc - v8utils.cc - variables.cc - version.cc - zone.cc - """), - 'arch:arm': Split(""" - arm/builtins-arm.cc - arm/code-stubs-arm.cc - arm/codegen-arm.cc - arm/constants-arm.cc - arm/cpu-arm.cc - arm/debug-arm.cc - arm/deoptimizer-arm.cc - arm/disasm-arm.cc - arm/frames-arm.cc - arm/full-codegen-arm.cc - arm/ic-arm.cc - arm/lithium-arm.cc - arm/lithium-codegen-arm.cc - arm/lithium-gap-resolver-arm.cc - arm/macro-assembler-arm.cc - arm/regexp-macro-assembler-arm.cc - arm/stub-cache-arm.cc - arm/assembler-arm.cc - """), - 'arch:mips': Split(""" - mips/assembler-mips.cc - mips/builtins-mips.cc - mips/code-stubs-mips.cc - mips/codegen-mips.cc - mips/constants-mips.cc - mips/cpu-mips.cc - mips/debug-mips.cc - mips/deoptimizer-mips.cc - mips/disasm-mips.cc - mips/frames-mips.cc - mips/full-codegen-mips.cc - mips/ic-mips.cc - mips/lithium-codegen-mips.cc - mips/lithium-gap-resolver-mips.cc - mips/lithium-mips.cc - mips/macro-assembler-mips.cc - mips/regexp-macro-assembler-mips.cc - mips/stub-cache-mips.cc - """), - 'arch:ia32': Split(""" - ia32/assembler-ia32.cc - ia32/builtins-ia32.cc - ia32/code-stubs-ia32.cc - ia32/codegen-ia32.cc - ia32/cpu-ia32.cc - ia32/debug-ia32.cc - ia32/deoptimizer-ia32.cc - ia32/disasm-ia32.cc - ia32/frames-ia32.cc - ia32/full-codegen-ia32.cc - ia32/ic-ia32.cc - ia32/lithium-codegen-ia32.cc - ia32/lithium-gap-resolver-ia32.cc - ia32/lithium-ia32.cc - ia32/macro-assembler-ia32.cc - ia32/regexp-macro-assembler-ia32.cc - ia32/stub-cache-ia32.cc - """), - 'arch:x64': Split(""" - x64/assembler-x64.cc - x64/builtins-x64.cc - x64/code-stubs-x64.cc - x64/codegen-x64.cc - x64/cpu-x64.cc - x64/debug-x64.cc - x64/deoptimizer-x64.cc - x64/disasm-x64.cc - x64/frames-x64.cc - x64/full-codegen-x64.cc - x64/ic-x64.cc - x64/lithium-codegen-x64.cc - x64/lithium-gap-resolver-x64.cc - x64/lithium-x64.cc - x64/macro-assembler-x64.cc - x64/regexp-macro-assembler-x64.cc - x64/stub-cache-x64.cc - """), - 'simulator:arm': ['arm/simulator-arm.cc'], - 'simulator:mips': ['mips/simulator-mips.cc'], - 'os:freebsd': ['platform-freebsd.cc', 'platform-posix.cc'], - 'os:openbsd': ['platform-openbsd.cc', 'platform-posix.cc'], - 'os:linux': ['platform-linux.cc', 'platform-posix.cc'], - 'os:android': ['platform-linux.cc', 'platform-posix.cc'], - 'os:macos': ['platform-macos.cc', 'platform-posix.cc'], - 'os:solaris': ['platform-solaris.cc', 'platform-posix.cc'], - 'os:cygwin': ['platform-cygwin.cc', 'platform-posix.cc'], - 'os:nullos': ['platform-nullos.cc'], - 'os:win32': ['platform-win32.cc', 'win32-math.cc'], - 'mode:release': [], - 'mode:debug': [ - 'objects-debug.cc', 'prettyprinter.cc', 'regexp-macro-assembler-tracer.cc' - ] -} - - -PREPARSER_SOURCES = { - 'all': Split(""" - allocation.cc - bignum.cc - bignum-dtoa.cc - cached-powers.cc - conversions.cc - diy-fp.cc - dtoa.cc - fast-dtoa.cc - fixed-dtoa.cc - preparse-data.cc - preparser.cc - preparser-api.cc - scanner.cc - strtod.cc - token.cc - unicode.cc - utils.cc - """), - 'os:win32': ['win32-math.cc'] -} - - -D8_LIGHT_FILES = { - 'all': [ - 'd8.cc' - ] -} - - -D8_FULL_FILES = { - 'all': [ - 'd8.cc', 'd8-debug.cc' - ], - 'os:linux': [ - 'd8-posix.cc' - ], - 'os:macos': [ - 'd8-posix.cc' - ], - 'os:android': [ - 'd8-posix.cc' - ], - 'os:freebsd': [ - 'd8-posix.cc' - ], - 'os:openbsd': [ - 'd8-posix.cc' - ], - 'os:solaris': [ - 'd8-posix.cc' - ], - 'os:cygwin': [ - 'd8-posix.cc' - ], - 'os:win32': [ - 'd8-windows.cc' - ], - 'os:nullos': [ - 'd8-windows.cc' # Empty implementation at the moment. - ], - 'console:readline': [ - 'd8-readline.cc' - ] -} - - -LIBRARY_FILES = ''' -runtime.js -v8natives.js -array.js -string.js -uri.js -math.js -messages.js -apinatives.js -date.js -regexp.js -json.js -liveedit-debugger.js -mirror-debugger.js -debug-debugger.js -'''.split() - - -EXPERIMENTAL_LIBRARY_FILES = ''' -symbol.js -proxy.js -collection.js -'''.split() - - -def Abort(message): - print message - sys.exit(1) - - -def ConfigureObjectFiles(): - env = Environment(tools=tools) - env.Replace(**context.flags['v8']) - context.ApplyEnvOverrides(env) - env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C) - env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions') - - def BuildJS2CEnv(type): - js2c_env = { 'TYPE': type, 'COMPRESSION': 'off' } - if 'COMPRESS_STARTUP_DATA_BZ2' in env['CPPDEFINES']: - js2c_env['COMPRESSION'] = 'bz2' - return js2c_env - - # Build the standard platform-independent source files. - source_files = context.GetRelevantSources(SOURCES) - d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'}) - d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.']) - if context.options['library'] == 'shared': - d8_files = context.GetRelevantSources(D8_LIGHT_FILES) - d8_objs = [] - else: - d8_files = context.GetRelevantSources(D8_FULL_FILES) - d8_objs = [d8_js_obj] - d8_objs.append(context.ConfigureObject(d8_env, [d8_files])) - - # Combine the JavaScript library files into a single C++ file and - # compile it. - library_files = [s for s in LIBRARY_FILES] - library_files.append('macros.py') - libraries_src = env.JS2C( - ['libraries.cc'], library_files, **BuildJS2CEnv('CORE')) - libraries_obj = context.ConfigureObject(env, libraries_src, CPPPATH=['.']) - - # Combine the experimental JavaScript library files into a C++ file - # and compile it. - experimental_library_files = [ s for s in EXPERIMENTAL_LIBRARY_FILES ] - experimental_library_files.append('macros.py') - experimental_libraries_src = env.JS2C(['experimental-libraries.cc'], - experimental_library_files, - **BuildJS2CEnv('EXPERIMENTAL')) - experimental_libraries_obj = context.ConfigureObject(env, experimental_libraries_src, CPPPATH=['.']) - - source_objs = context.ConfigureObject(env, source_files) - non_snapshot_files = [source_objs] - - preparser_source_files = context.GetRelevantSources(PREPARSER_SOURCES) - preparser_objs = context.ConfigureObject(env, preparser_source_files) - - # Create snapshot if necessary. For cross compilation you should either - # do without snapshots and take the performance hit or you should build a - # host VM with the simulator=arm and snapshot=on options and then take the - # resulting snapshot.cc file from obj/release and put it in the src - # directory. Then rebuild the VM with the cross compiler and specify - # snapshot=nobuild on the scons command line. - empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc') - mksnapshot_env = env.Copy() - mksnapshot_env.Replace(**context.flags['mksnapshot']) - mksnapshot_src = 'mksnapshot.cc' - mksnapshot = mksnapshot_env.Program('mksnapshot', [mksnapshot_src, libraries_obj, experimental_libraries_obj, non_snapshot_files, empty_snapshot_obj], PDB='mksnapshot.exe.pdb') - if context.use_snapshot: - if context.build_snapshot: - snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath) - else: - snapshot_cc = 'snapshot.cc' - snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.']) - else: - snapshot_obj = empty_snapshot_obj - library_objs = [non_snapshot_files, libraries_obj, experimental_libraries_obj, snapshot_obj] - return (library_objs, d8_objs, [mksnapshot], preparser_objs) - - -(library_objs, d8_objs, mksnapshot, preparser_objs) = ConfigureObjectFiles() -Return('library_objs d8_objs mksnapshot preparser_objs') diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index dddcd7dcf5..15831ec6a8 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -623,6 +623,9 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) { if (IsDeadCheck(isolate, "V8::Persistent::New")) return NULL; LOG_API(isolate, "Persistent::New"); i::Handle<i::Object> result = isolate->global_handles()->Create(*obj); +#ifdef DEBUG + (*obj)->Verify(); +#endif // DEBUG return result.location(); } diff --git a/deps/v8/src/arguments.h b/deps/v8/src/arguments.h index 1423d5642b..f8fb00c575 100644 --- a/deps/v8/src/arguments.h +++ b/deps/v8/src/arguments.h @@ -115,18 +115,15 @@ class CustomArguments : public Relocatable { #define DECLARE_RUNTIME_FUNCTION(Type, Name) \ -Type Name(int args_length, Object** args_object, Isolate* isolate) - -#define RUNTIME_FUNCTION(Type, Name) \ -static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \ -Type Name(int args_length, Object** args_object, Isolate* isolate) { \ - Arguments args(args_length, args_object); \ - return __RT_impl_##Name(args, isolate); \ -} \ -static Type __RT_impl_##Name(Arguments args, Isolate* isolate) - -#define RUNTIME_ARGUMENTS(isolate, args) \ - args.length(), args.arguments(), isolate +Type Name(Arguments args, Isolate* isolate) + + +#define RUNTIME_FUNCTION(Type, Name) \ +Type Name(Arguments args, Isolate* isolate) + + +#define RUNTIME_ARGUMENTS(isolate, args) args, isolate + } } // namespace v8::internal diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h index 0f9630b341..1e0d5c1f7d 100644 --- a/deps/v8/src/arm/assembler-arm-inl.h +++ b/deps/v8/src/arm/assembler-arm-inl.h @@ -266,19 +266,11 @@ Object** RelocInfo::call_object_address() { bool RelocInfo::IsPatchedReturnSequence() { Instr current_instr = Assembler::instr_at(pc_); Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize); -#ifdef USE_BLX // A patched return sequence is: // ldr ip, [pc, #0] // blx ip return ((current_instr & kLdrPCMask) == kLdrPCPattern) && ((next_instr & kBlxRegMask) == kBlxRegPattern); -#else - // A patched return sequence is: - // mov lr, pc - // ldr pc, [pc, #-4] - return (current_instr == kMovLrPc) - && ((next_instr & kLdrPCMask) == kLdrPCPattern); -#endif } @@ -408,14 +400,11 @@ Address Assembler::target_pointer_address_at(Address pc) { instr = Memory::int32_at(target_pc); } -#ifdef USE_BLX - // If we have a blx instruction, the instruction before it is - // what needs to be patched. + // With a blx instruction, the instruction before is what needs to be patched. if ((instr & kBlxRegMask) == kBlxRegPattern) { target_pc -= kInstrSize; instr = Memory::int32_at(target_pc); } -#endif ASSERT(IsLdrPcImmediateOffset(instr)); int offset = instr & 0xfff; // offset_12 is unsigned @@ -442,7 +431,6 @@ Address Assembler::target_pointer_at(Address pc) { Address Assembler::target_address_from_return_address(Address pc) { // Returns the address of the call target from the return address that will // be returned to after a call. -#ifdef USE_BLX // Call sequence on V7 or later is : // movw ip, #... @ call address low 16 // movt ip, #... @ call address high 16 @@ -461,18 +449,10 @@ Address Assembler::target_address_from_return_address(Address pc) { ASSERT(IsMovW(Memory::int32_at(candidate)) && IsMovT(Memory::int32_at(candidate + kInstrSize))); return candidate; -#else - // Call sequence is: - // mov lr, pc - // ldr pc, [pc, #...] @ call address - // @ return address - return pc - kInstrSize; -#endif } Address Assembler::return_address_from_call_start(Address pc) { -#ifdef USE_BLX if (IsLdrPcImmediateOffset(Memory::int32_at(pc))) { return pc + kInstrSize * 2; } else { @@ -480,9 +460,6 @@ Address Assembler::return_address_from_call_start(Address pc) { ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); return pc + kInstrSize * 3; } -#else - return pc + kInstrSize; -#endif } diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index bc21b64017..b473c6b52b 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -1683,7 +1683,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) { emit(reinterpret_cast<Instr>(msg)); } #else // def __arm__ -#ifdef CAN_USE_ARMV5_INSTRUCTIONS if (cond != al) { Label skip; b(&skip, NegateCondition(cond)); @@ -1692,9 +1691,6 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) { } else { bkpt(0); } -#else // ndef CAN_USE_ARMV5_INSTRUCTIONS - svc(0x9f0001, cond); -#endif // ndef CAN_USE_ARMV5_INSTRUCTIONS #endif // def __arm__ } diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index 0aecbcdd61..0fd5186734 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -663,37 +663,19 @@ class Assembler : public AssemblerBase { // Distance between start of patched return sequence and the emitted address // to jump to. -#ifdef USE_BLX // Patched return sequence is: // ldr ip, [pc, #0] @ emited address and start // blx ip static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize; -#else - // Patched return sequence is: - // mov lr, pc @ start of sequence - // ldr pc, [pc, #-4] @ emited address - static const int kPatchReturnSequenceAddressOffset = kInstrSize; -#endif // Distance between start of patched debug break slot and the emitted address // to jump to. -#ifdef USE_BLX // Patched debug break slot code is: // ldr ip, [pc, #0] @ emited address and start // blx ip static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; -#else - // Patched debug break slot code is: - // mov lr, pc @ start of sequence - // ldr pc, [pc, #-4] @ emited address - static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; -#endif -#ifdef USE_BLX static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize; -#else - static const int kPatchDebugBreakSlotReturnOffset = kInstrSize; -#endif // Difference between address of current opcode and value read from pc // register. @@ -1130,16 +1112,8 @@ class Assembler : public AssemblerBase { static bool use_immediate_embedded_pointer_loads( const Assembler* assembler) { -#ifdef USE_BLX return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) && (assembler == NULL || !assembler->predictable_code_size()); -#else - // If not using BLX, all loads from the constant pool cannot be immediate, - // because the ldr pc, [pc + #xxxx] used for calls must be a single - // instruction and cannot be easily distinguished out of context from - // other loads that could use movw/movt. - return false; -#endif } // Check the code size generated from label to here. diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index 1db415292a..ef2dbb3892 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -30,7 +30,6 @@ #if defined(V8_TARGET_ARCH_ARM) #include "bootstrapper.h" -#include "builtins-decls.h" #include "code-stubs.h" #include "regexp-macro-assembler.h" #include "stub-cache.h" @@ -482,9 +481,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) { __ Ret(); __ bind(¬_special); - // Count leading zeros. Uses mantissa for a scratch register on pre-ARM5. - // Gets the wrong answer for 0, but we already checked for that case above. - __ CountLeadingZeros(zeros_, source_, mantissa); + __ clz(zeros_, source_); // Compute exponent and or it into the exponent register. // We use mantissa as a scratch register here. Use a fudge factor to // divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts @@ -2032,7 +2029,7 @@ void BinaryOpStub_GenerateSmiSmiOperation(MacroAssembler* masm, } // Perform division by shifting. - __ CountLeadingZeros(scratch1, scratch1, scratch2); + __ clz(scratch1, scratch1); __ rsb(scratch1, scratch1, Operand(31)); __ mov(right, Operand(left, LSR, scratch1)); __ Ret(); diff --git a/deps/v8/src/arm/code-stubs-arm.h b/deps/v8/src/arm/code-stubs-arm.h index 741ff9ca83..75cbf6582c 100644 --- a/deps/v8/src/arm/code-stubs-arm.h +++ b/deps/v8/src/arm/code-stubs-arm.h @@ -130,7 +130,7 @@ class UnaryOpStub: public PlatformCodeStub { void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm); - virtual int GetCodeKind() { return Code::UNARY_OP_IC; } + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } virtual InlineCacheState GetICState() { return UnaryOpIC::ToState(operand_type_); diff --git a/deps/v8/src/arm/constants-arm.h b/deps/v8/src/arm/constants-arm.h index 747dc5627a..e21055fee4 100644 --- a/deps/v8/src/arm/constants-arm.h +++ b/deps/v8/src/arm/constants-arm.h @@ -33,13 +33,6 @@ #error ARM EABI support is required. #endif -// This means that interwork-compatible jump instructions are generated. We -// want to generate them on the simulator too so it makes snapshots that can -// be used on real hardware. -#if defined(__THUMB_INTERWORK__) || !defined(__arm__) -# define USE_THUMB_INTERWORK 1 -#endif - #if defined(__ARM_ARCH_7A__) || \ defined(__ARM_ARCH_7R__) || \ defined(__ARM_ARCH_7__) @@ -49,39 +42,11 @@ #endif #endif -#if defined(__ARM_ARCH_6__) || \ - defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6K__) || \ - defined(__ARM_ARCH_6Z__) || \ - defined(__ARM_ARCH_6ZK__) || \ - defined(__ARM_ARCH_6T2__) || \ - defined(CAN_USE_ARMV7_INSTRUCTIONS) -# define CAN_USE_ARMV6_INSTRUCTIONS 1 -#endif - -#if defined(__ARM_ARCH_5__) || \ - defined(__ARM_ARCH_5T__) || \ - defined(__ARM_ARCH_5TE__) || \ - defined(__ARM_ARCH_5TEJ__) || \ - defined(CAN_USE_ARMV6_INSTRUCTIONS) -# define CAN_USE_ARMV5_INSTRUCTIONS 1 -# define CAN_USE_THUMB_INSTRUCTIONS 1 -#endif - -// Simulator should support ARM5 instructions and unaligned access by default. +// Simulator should support unaligned access by default. #if !defined(__arm__) -# define CAN_USE_ARMV5_INSTRUCTIONS 1 -# define CAN_USE_THUMB_INSTRUCTIONS 1 - # ifndef CAN_USE_UNALIGNED_ACCESSES # define CAN_USE_UNALIGNED_ACCESSES 1 # endif - -#endif - -// Using blx may yield better code, so use it when required or when available -#if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS) -#define USE_BLX 1 #endif namespace v8 { diff --git a/deps/v8/src/arm/cpu-arm.cc b/deps/v8/src/arm/cpu-arm.cc index 7b08ed8c2f..101cd9f143 100644 --- a/deps/v8/src/arm/cpu-arm.cc +++ b/deps/v8/src/arm/cpu-arm.cc @@ -108,7 +108,7 @@ void CPU::FlushICache(void* start, size_t size) { void CPU::DebugBreak() { -#if !defined (__arm__) || !defined(CAN_USE_ARMV5_INSTRUCTIONS) +#if !defined (__arm__) UNIMPLEMENTED(); // when building ARM emulator target #else asm volatile("bkpt 0"); diff --git a/deps/v8/src/arm/debug-arm.cc b/deps/v8/src/arm/debug-arm.cc index e9a65b2b0f..848fae20d5 100644 --- a/deps/v8/src/arm/debug-arm.cc +++ b/deps/v8/src/arm/debug-arm.cc @@ -48,23 +48,13 @@ void BreakLocationIterator::SetDebugBreakAtReturn() { // add sp, sp, #4 // bx lr // to a call to the debug break return code. - // #ifdef USE_BLX // ldr ip, [pc, #0] // blx ip - // #else - // mov lr, pc - // ldr pc, [pc, #-4] - // #endif // <debug break return code entry point address> // bktp 0 CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); -#ifdef USE_BLX patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); patcher.masm()->blx(v8::internal::ip); -#else - patcher.masm()->mov(v8::internal::lr, v8::internal::pc); - patcher.masm()->ldr(v8::internal::pc, MemOperand(v8::internal::pc, -4)); -#endif patcher.Emit(Isolate::Current()->debug()->debug_break_return()->entry()); patcher.masm()->bkpt(0); } @@ -99,22 +89,12 @@ void BreakLocationIterator::SetDebugBreakAtSlot() { // mov r2, r2 // mov r2, r2 // to a call to the debug break slot code. - // #ifdef USE_BLX // ldr ip, [pc, #0] // blx ip - // #else - // mov lr, pc - // ldr pc, [pc, #-4] - // #endif // <debug break slot code entry point address> CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); -#ifdef USE_BLX patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); patcher.masm()->blx(v8::internal::ip); -#else - patcher.masm()->mov(v8::internal::lr, v8::internal::pc); - patcher.masm()->ldr(v8::internal::pc, MemOperand(v8::internal::pc, -4)); -#endif patcher.Emit(Isolate::Current()->debug()->debug_break_slot()->entry()); } diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index ba0f141289..6a33234031 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -3976,18 +3976,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::ADD: { - Comment cmt(masm_, "[ UnaryOperation (ADD)"); - VisitForAccumulatorValue(expr->expression()); - Label no_conversion; - __ JumpIfSmi(result_register(), &no_conversion); - ToNumberStub convert_stub; - __ CallStub(&convert_stub); - __ bind(&no_conversion); - context()->Plug(result_register()); - break; - } - case Token::SUB: EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); break; diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index f6029b5143..64083e8597 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -823,11 +823,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { HEnvironment* last_environment = pred->last_environment(); for (int i = 0; i < block->phis()->length(); ++i) { HPhi* phi = block->phis()->at(i); - last_environment->SetValueAt(phi->merged_index(), phi); + if (phi->merged_index() < last_environment->length()) { + last_environment->SetValueAt(phi->merged_index(), phi); + } } for (int i = 0; i < block->deleted_phis()->length(); ++i) { - last_environment->SetValueAt(block->deleted_phis()->at(i), - graph_->GetConstantUndefined()); + if (block->deleted_phis()->at(i) < last_environment->length()) { + last_environment->SetValueAt(block->deleted_phis()->at(i), + graph_->GetConstantUndefined()); + } } block->UpdateEnvironment(last_environment); // Pick up the outgoing argument count of one of the predecessors. diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index a19015d807..d2f44b05c0 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -304,7 +304,7 @@ bool LCodeGen::GenerateDeferredCode() { LDeferredCode* code = deferred_[i]; __ bind(code->entry()); if (NeedsDeferredFrame()) { - Comment(";;; Deferred build frame", + Comment(";;; Deferred build frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(!frame_is_built_); @@ -320,7 +320,7 @@ bool LCodeGen::GenerateDeferredCode() { code->instr()->Mnemonic()); code->Generate(); if (NeedsDeferredFrame()) { - Comment(";;; Deferred destroy frame", + Comment(";;; Deferred destroy frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(frame_is_built_); @@ -1043,11 +1043,9 @@ void LCodeGen::RecordPosition(int position) { void LCodeGen::DoLabel(LLabel* label) { - if (label->is_loop_header()) { - Comment(";;; B%d - LOOP entry", label->block_id()); - } else { - Comment(";;; B%d", label->block_id()); - } + Comment(";;; -------------------- B%d%s --------------------", + label->block_id(), + label->is_loop_header() ? " (loop header)" : ""); __ bind(label->label()); current_block_ = label->block_id(); DoGap(label); @@ -2055,33 +2053,38 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); HMathMinMax::Operation operation = instr->hydrogen()->operation(); - Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; if (instr->hydrogen()->representation().IsInteger32()) { + Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; Register left_reg = ToRegister(left); Operand right_op = (right->IsRegister() || right->IsConstantOperand()) ? ToOperand(right) : Operand(EmitLoadRegister(right, ip)); Register result_reg = ToRegister(instr->result()); __ cmp(left_reg, right_op); - if (!result_reg.is(left_reg)) { - __ mov(result_reg, left_reg, LeaveCC, condition); - } + __ Move(result_reg, left_reg, condition); __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); } else { ASSERT(instr->hydrogen()->representation().IsDouble()); DwVfpRegister left_reg = ToDoubleRegister(left); DwVfpRegister right_reg = ToDoubleRegister(right); DwVfpRegister result_reg = ToDoubleRegister(instr->result()); - Label check_nan_left, check_zero, return_left, return_right, done; + Label result_is_nan, return_left, return_right, check_zero, done; __ VFPCompareAndSetFlags(left_reg, right_reg); - __ b(vs, &check_nan_left); - __ b(eq, &check_zero); - __ b(condition, &return_left); - __ b(al, &return_right); - - __ bind(&check_zero); + if (operation == HMathMinMax::kMathMin) { + __ b(mi, &return_left); + __ b(gt, &return_right); + } else { + __ b(mi, &return_right); + __ b(gt, &return_left); + } + __ b(vs, &result_is_nan); + // Left equals right => check for -0. __ VFPCompareAndSetFlags(left_reg, 0.0); - __ b(ne, &return_left); // left == right != 0. + if (left_reg.is(result_reg) || right_reg.is(result_reg)) { + __ b(ne, &done); // left == right != 0. + } else { + __ b(ne, &return_left); // left == right != 0. + } // At this point, both left and right are either 0 or -0. if (operation == HMathMinMax::kMathMin) { // We could use a single 'vorr' instruction here if we had NEON support. @@ -2093,21 +2096,21 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { // the decision for vadd is easy because vand is a NEON instruction. __ vadd(result_reg, left_reg, right_reg); } - __ b(al, &done); + __ b(&done); + + __ bind(&result_is_nan); + __ vadd(result_reg, left_reg, right_reg); + __ b(&done); - __ bind(&check_nan_left); - __ VFPCompareAndSetFlags(left_reg, left_reg); - __ b(vs, &return_left); // left == NaN. __ bind(&return_right); - if (!right_reg.is(result_reg)) { - __ vmov(result_reg, right_reg); + __ Move(result_reg, right_reg); + if (!left_reg.is(result_reg)) { + __ b(&done); } - __ b(al, &done); __ bind(&return_left); - if (!left_reg.is(result_reg)) { - __ vmov(result_reg, left_reg); - } + __ Move(result_reg, left_reg); + __ bind(&done); } } @@ -2205,12 +2208,10 @@ void LCodeGen::DoBranch(LBranch* instr) { EmitBranch(true_block, false_block, ne); } else if (r.IsDouble()) { DwVfpRegister reg = ToDoubleRegister(instr->value()); - Register scratch = scratch0(); - // Test the double value. Zero and NaN are false. - __ VFPCompareAndLoadFlags(reg, 0.0, scratch); - __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); - EmitBranch(true_block, false_block, eq); + __ VFPCompareAndSetFlags(reg, 0.0); + __ cmp(r0, r0, vs); // If NaN, set the Z flag. + EmitBranch(true_block, false_block, ne); } else { ASSERT(r.IsTagged()); Register reg = ToRegister(instr->value()); @@ -2302,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) { __ b(ne, ¬_heap_number); __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); __ VFPCompareAndSetFlags(dbl_scratch, 0.0); - __ b(vs, false_label); // NaN -> false. + __ cmp(r0, r0, vs); // NaN -> false. __ b(eq, false_label); // +0, -0 -> false. __ b(true_label); __ bind(¬_heap_number); diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h index 3e24dae54c..c55558cff5 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.h +++ b/deps/v8/src/arm/lithium-codegen-arm.h @@ -29,10 +29,12 @@ #define V8_ARM_LITHIUM_CODEGEN_ARM_H_ #include "arm/lithium-arm.h" + #include "arm/lithium-gap-resolver-arm.h" #include "deoptimizer.h" #include "safepoint-table.h" #include "scopes.h" +#include "v8utils.h" namespace v8 { namespace internal { @@ -211,7 +213,7 @@ class LCodeGen BASE_EMBEDDED { int GetStackSlotCount() const { return chunk()->spill_slot_count(); } void Abort(const char* reason); - void Comment(const char* format, ...); + void FPRINTF_CHECKING Comment(const char* format, ...); void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 7df0c0a1ff..616d02d867 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -51,44 +51,15 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) } -// We always generate arm code, never thumb code, even if V8 is compiled to -// thumb, so we require inter-working support -#if defined(__thumb__) && !defined(USE_THUMB_INTERWORK) -#error "flag -mthumb-interwork missing" -#endif - - -// We do not support thumb inter-working with an arm architecture not supporting -// the blx instruction (below v5t). If you know what CPU you are compiling for -// you can use -march=armv7 or similar. -#if defined(USE_THUMB_INTERWORK) && !defined(CAN_USE_THUMB_INSTRUCTIONS) -# error "For thumb inter-working we require an architecture which supports blx" -#endif - - -// Using bx does not yield better code, so use it only when required -#if defined(USE_THUMB_INTERWORK) -#define USE_BX 1 -#endif - - void MacroAssembler::Jump(Register target, Condition cond) { -#if USE_BX bx(target, cond); -#else - mov(pc, Operand(target), LeaveCC, cond); -#endif } void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond) { -#if USE_BX mov(ip, Operand(target, rmode)); bx(ip, cond); -#else - mov(pc, Operand(target, rmode), LeaveCC, cond); -#endif } @@ -108,11 +79,7 @@ void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode, int MacroAssembler::CallSize(Register target, Condition cond) { -#ifdef USE_BLX return kInstrSize; -#else - return 2 * kInstrSize; -#endif } @@ -121,13 +88,7 @@ void MacroAssembler::Call(Register target, Condition cond) { BlockConstPoolScope block_const_pool(this); Label start; bind(&start); -#ifdef USE_BLX blx(target, cond); -#else - // set lr for return at current pc + 8 - mov(lr, Operand(pc), LeaveCC, cond); - mov(pc, Operand(target), LeaveCC, cond); -#endif ASSERT_EQ(CallSize(target, cond), SizeOfCodeGeneratedSince(&start)); } @@ -170,7 +131,6 @@ void MacroAssembler::Call(Address target, set_predictable_code_size(true); } -#ifdef USE_BLX // Call sequence on V7 or later may be : // movw ip, #... @ call address low 16 // movt ip, #... @ call address high 16 @@ -191,12 +151,6 @@ void MacroAssembler::Call(Address target, mov(ip, Operand(reinterpret_cast<int32_t>(target), rmode)); blx(ip, cond); -#else - // Set lr for return at current pc + 8. - mov(lr, Operand(pc), LeaveCC, cond); - // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. - mov(pc, Operand(reinterpret_cast<int32_t>(target), rmode), LeaveCC, cond); -#endif ASSERT_EQ(CallSize(target, rmode, cond), SizeOfCodeGeneratedSince(&start)); if (mode == NEVER_INLINE_TARGET_ADDRESS) { set_predictable_code_size(old_predictable_code_size); @@ -230,11 +184,7 @@ void MacroAssembler::Call(Handle<Code> code, void MacroAssembler::Ret(Condition cond) { -#if USE_BX bx(lr, cond); -#else - mov(pc, Operand(lr), LeaveCC, cond); -#endif } @@ -3226,44 +3176,6 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, } -void MacroAssembler::CountLeadingZeros(Register zeros, // Answer. - Register source, // Input. - Register scratch) { - ASSERT(!zeros.is(source) || !source.is(scratch)); - ASSERT(!zeros.is(scratch)); - ASSERT(!scratch.is(ip)); - ASSERT(!source.is(ip)); - ASSERT(!zeros.is(ip)); -#ifdef CAN_USE_ARMV5_INSTRUCTIONS - clz(zeros, source); // This instruction is only supported after ARM5. -#else - // Order of the next two lines is important: zeros register - // can be the same as source register. - Move(scratch, source); - mov(zeros, Operand::Zero()); - // Top 16. - tst(scratch, Operand(0xffff0000)); - add(zeros, zeros, Operand(16), LeaveCC, eq); - mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq); - // Top 8. - tst(scratch, Operand(0xff000000)); - add(zeros, zeros, Operand(8), LeaveCC, eq); - mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq); - // Top 4. - tst(scratch, Operand(0xf0000000)); - add(zeros, zeros, Operand(4), LeaveCC, eq); - mov(scratch, Operand(scratch, LSL, 4), LeaveCC, eq); - // Top 2. - tst(scratch, Operand(0xc0000000)); - add(zeros, zeros, Operand(2), LeaveCC, eq); - mov(scratch, Operand(scratch, LSL, 2), LeaveCC, eq); - // Top bit. - tst(scratch, Operand(0x80000000u)); - add(zeros, zeros, Operand(1), LeaveCC, eq); -#endif -} - - void MacroAssembler::CheckFor32DRegs(Register scratch) { mov(scratch, Operand(ExternalReference::cpu_features())); ldr(scratch, MemOperand(scratch)); diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index 86ae8f22d9..f9f672bac6 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -993,15 +993,6 @@ class MacroAssembler: public Assembler { Register input_high, Register input_low); - // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz - // instruction. On pre-ARM5 hardware this routine gives the wrong answer - // for 0 (31 instead of 32). Source and scratch can be the same in which case - // the source is clobbered. Source and zeros can also be the same in which - // case scratch should be a different register. - void CountLeadingZeros(Register zeros, - Register source, - Register scratch); - // Check whether d16-d31 are available on the CPU. The result is given by the // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise. void CheckFor32DRegs(Register scratch); diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc index ad4d77df28..ea79310447 100644 --- a/deps/v8/src/arm/simulator-arm.cc +++ b/deps/v8/src/arm/simulator-arm.cc @@ -975,14 +975,12 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) { } -// Runtime FP routines take up to two double arguments and zero -// or one integer arguments. All are constructed here, +// For use in calls that take two double values, constructed either // from r0-r3 or d0 and d1. -void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { +void Simulator::GetFpArgs(double* x, double* y) { if (use_eabi_hardfloat()) { *x = vfp_registers_[0]; *y = vfp_registers_[1]; - *z = registers_[1]; } else { // We use a char buffer to get around the strict-aliasing rules which // otherwise allow the compiler to optimize away the copy. @@ -993,9 +991,41 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { // Registers 2 and 3 -> y. OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); OS::MemCopy(y, buffer, sizeof(*y)); - // Register 2 -> z. - OS::MemCopy(buffer, registers_ + 2, sizeof(*z)); - OS::MemCopy(z, buffer, sizeof(*z)); + } +} + +// For use in calls that take one double value, constructed either +// from r0 and r1 or d0. +void Simulator::GetFpArgs(double* x) { + if (use_eabi_hardfloat()) { + *x = vfp_registers_[0]; + } else { + // We use a char buffer to get around the strict-aliasing rules which + // otherwise allow the compiler to optimize away the copy. + char buffer[sizeof(*x)]; + // Registers 0 and 1 -> x. + OS::MemCopy(buffer, registers_, sizeof(*x)); + OS::MemCopy(x, buffer, sizeof(*x)); + } +} + + +// For use in calls that take one double value constructed either +// from r0 and r1 or d0 and one integer value. +void Simulator::GetFpArgs(double* x, int32_t* y) { + if (use_eabi_hardfloat()) { + *x = vfp_registers_[0]; + *y = registers_[1]; + } else { + // We use a char buffer to get around the strict-aliasing rules which + // otherwise allow the compiler to optimize away the copy. + char buffer[sizeof(*x)]; + // Registers 0 and 1 -> x. + OS::MemCopy(buffer, registers_, sizeof(*x)); + OS::MemCopy(x, buffer, sizeof(*x)); + // Register 2 -> y. + OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); + OS::MemCopy(y, buffer, sizeof(*y)); } } @@ -1618,12 +1648,10 @@ typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, int32_t arg3, int32_t arg4, int32_t arg5); - -// These prototypes handle the four types of FP calls. -typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1); -typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); -typedef double (*SimulatorRuntimeFPCall)(double darg0); -typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0); +typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, + int32_t arg1, + int32_t arg2, + int32_t arg3); // This signature supports direct call in to API function native callback // (refer to InvocationCallback in v8.h). @@ -1689,27 +1717,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { intptr_t external = reinterpret_cast<intptr_t>(redirection->external_function()); if (fp_call) { - double dval0, dval1; // one or two double parameters - int32_t ival; // zero or one integer parameters - int64_t iresult = 0; // integer return value - double dresult = 0; // double return value - GetFpArgs(&dval0, &dval1, &ival); if (::v8::internal::FLAG_trace_sim || !stack_aligned) { - SimulatorRuntimeCall generic_target = - reinterpret_cast<SimulatorRuntimeCall>(external); + SimulatorRuntimeFPCall target = + reinterpret_cast<SimulatorRuntimeFPCall>(external); + double dval0, dval1; + int32_t ival; switch (redirection->type()) { case ExternalReference::BUILTIN_FP_FP_CALL: case ExternalReference::BUILTIN_COMPARE_CALL: + GetFpArgs(&dval0, &dval1); PrintF("Call to host function at %p with args %f, %f", - FUNCTION_ADDR(generic_target), dval0, dval1); + FUNCTION_ADDR(target), dval0, dval1); break; case ExternalReference::BUILTIN_FP_CALL: + GetFpArgs(&dval0); PrintF("Call to host function at %p with arg %f", - FUNCTION_ADDR(generic_target), dval0); + FUNCTION_ADDR(target), dval0); break; case ExternalReference::BUILTIN_FP_INT_CALL: + GetFpArgs(&dval0, &ival); PrintF("Call to host function at %p with args %f, %d", - FUNCTION_ADDR(generic_target), dval0, ival); + FUNCTION_ADDR(target), dval0, ival); break; default: UNREACHABLE(); @@ -1721,54 +1749,22 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { PrintF("\n"); } CHECK(stack_aligned); - switch (redirection->type()) { - case ExternalReference::BUILTIN_COMPARE_CALL: { - SimulatorRuntimeCompareCall target = - reinterpret_cast<SimulatorRuntimeCompareCall>(external); - iresult = target(dval0, dval1); - set_register(r0, static_cast<int32_t>(iresult)); - set_register(r1, static_cast<int32_t>(iresult >> 32)); - break; - } - case ExternalReference::BUILTIN_FP_FP_CALL: { - SimulatorRuntimeFPFPCall target = - reinterpret_cast<SimulatorRuntimeFPFPCall>(external); - dresult = target(dval0, dval1); - SetFpResult(dresult); - break; - } - case ExternalReference::BUILTIN_FP_CALL: { + if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) { SimulatorRuntimeFPCall target = - reinterpret_cast<SimulatorRuntimeFPCall>(external); - dresult = target(dval0); - SetFpResult(dresult); - break; - } - case ExternalReference::BUILTIN_FP_INT_CALL: { - SimulatorRuntimeFPIntCall target = - reinterpret_cast<SimulatorRuntimeFPIntCall>(external); - dresult = target(dval0, ival); - SetFpResult(dresult); - break; - } - default: - UNREACHABLE(); - break; - } - if (::v8::internal::FLAG_trace_sim || !stack_aligned) { - switch (redirection->type()) { - case ExternalReference::BUILTIN_COMPARE_CALL: - PrintF("Returned %08x\n", static_cast<int32_t>(iresult)); - break; - case ExternalReference::BUILTIN_FP_FP_CALL: - case ExternalReference::BUILTIN_FP_CALL: - case ExternalReference::BUILTIN_FP_INT_CALL: - PrintF("Returned %f\n", dresult); - break; - default: - UNREACHABLE(); - break; + reinterpret_cast<SimulatorRuntimeFPCall>(external); + double result = target(arg0, arg1, arg2, arg3); + SetFpResult(result); + } else { + SimulatorRuntimeCall target = + reinterpret_cast<SimulatorRuntimeCall>(external); + int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); + int32_t lo_res = static_cast<int32_t>(result); + int32_t hi_res = static_cast<int32_t>(result >> 32); + if (::v8::internal::FLAG_trace_sim) { + PrintF("Returned %08x\n", lo_res); } + set_register(r0, lo_res); + set_register(r1, hi_res); } } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { SimulatorRuntimeDirectApiCall target = diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h index 45ae999b57..674ff42d63 100644 --- a/deps/v8/src/arm/simulator-arm.h +++ b/deps/v8/src/arm/simulator-arm.h @@ -348,8 +348,10 @@ class Simulator { void* external_function, v8::internal::ExternalReference::Type type); - // Handle arguments and return value for runtime FP functions. - void GetFpArgs(double* x, double* y, int32_t* z); + // For use in calls that take double value arguments. + void GetFpArgs(double* x, double* y); + void GetFpArgs(double* x); + void GetFpArgs(double* x, int32_t* y); void SetFpResult(const double& result); void TrashCallerSaveRegisters(); diff --git a/deps/v8/src/atomicops_internals_x86_gcc.h b/deps/v8/src/atomicops_internals_x86_gcc.h index e58d598fbd..6e55b50182 100644 --- a/deps/v8/src/atomicops_internals_x86_gcc.h +++ b/deps/v8/src/atomicops_internals_x86_gcc.h @@ -168,7 +168,7 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) { return *ptr; } -#if defined(__x86_64__) && defined(V8_HOST_ARCH_64_BIT) +#if defined(__x86_64__) // 64-bit low-level operations on 64-bit platform. diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc index 56c0501e57..30edf579e6 100644 --- a/deps/v8/src/builtins.cc +++ b/deps/v8/src/builtins.cc @@ -125,31 +125,23 @@ BUILTIN_LIST_C(DEF_ARG_TYPE) #ifdef DEBUG -#define BUILTIN(name) \ - MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ - name##ArgumentsType args, Isolate* isolate); \ - MUST_USE_RESULT static MaybeObject* Builtin_##name( \ - int args_length, Object** args_object, Isolate* isolate) { \ - name##ArgumentsType args(args_length, args_object); \ - ASSERT(isolate == Isolate::Current()); \ - args.Verify(); \ - return Builtin_Impl_##name(args, isolate); \ - } \ - MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ +#define BUILTIN(name) \ + MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ + name##ArgumentsType args, Isolate* isolate); \ + MUST_USE_RESULT static MaybeObject* Builtin_##name( \ + name##ArgumentsType args, Isolate* isolate) { \ + ASSERT(isolate == Isolate::Current()); \ + args.Verify(); \ + return Builtin_Impl_##name(args, isolate); \ + } \ + MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ name##ArgumentsType args, Isolate* isolate) #else // For release mode. -#define BUILTIN(name) \ - static MaybeObject* Builtin_impl##name( \ - name##ArgumentsType args, Isolate* isolate); \ - static MaybeObject* Builtin_##name( \ - int args_length, Object** args_object, Isolate* isolate) { \ - name##ArgumentsType args(args_length, args_object); \ - return Builtin_impl##name(args, isolate); \ - } \ - static MaybeObject* Builtin_impl##name( \ - name##ArgumentsType args, Isolate* isolate) +#define BUILTIN(name) \ + static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate) + #endif diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h index ee607ad304..12ed56af79 100644 --- a/deps/v8/src/builtins.h +++ b/deps/v8/src/builtins.h @@ -274,6 +274,8 @@ enum BuiltinExtraArguments { V(APPLY_PREPARE, 1) \ V(APPLY_OVERFLOW, 1) +MaybeObject* ArrayConstructor_StubFailure(Arguments args, Isolate* isolate); + class BuiltinFunctionTable; class ObjectVisitor; diff --git a/deps/v8/src/code-stubs-hydrogen.cc b/deps/v8/src/code-stubs-hydrogen.cc index 02c0091889..60ddf9b462 100644 --- a/deps/v8/src/code-stubs-hydrogen.cc +++ b/deps/v8/src/code-stubs-hydrogen.cc @@ -106,8 +106,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() { Zone* zone = this->zone(); int param_count = descriptor_->register_param_count_; HEnvironment* start_environment = graph()->start_environment(); - HBasicBlock* next_block = - CreateBasicBlock(start_environment, BailoutId::StubEntry()); + HBasicBlock* next_block = CreateBasicBlock(start_environment); current_block()->Goto(next_block); next_block->SetJoinId(BailoutId::StubEntry()); set_current_block(next_block); @@ -186,7 +185,7 @@ template <class Stub> static Handle<Code> DoGenerateCode(Stub* stub) { CodeStubGraphBuilder<Stub> builder(stub); LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return chunk->Codegen(); } @@ -212,23 +211,24 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); IfBuilder if_fixed_cow(this); - if_fixed_cow.BeginIfMapEquals(elements, factory->fixed_cow_array_map()); + if_fixed_cow.IfCompareMap(elements, factory->fixed_cow_array_map()); + if_fixed_cow.Then(); environment()->Push(BuildCloneShallowArray(context(), boilerplate, alloc_site_mode, FAST_ELEMENTS, 0/*copy-on-write*/)); - if_fixed_cow.BeginElse(); + if_fixed_cow.Else(); IfBuilder if_fixed(this); - if_fixed.BeginIfMapEquals(elements, factory->fixed_array_map()); + if_fixed.IfCompareMap(elements, factory->fixed_array_map()); + if_fixed.Then(); environment()->Push(BuildCloneShallowArray(context(), boilerplate, alloc_site_mode, FAST_ELEMENTS, length)); - if_fixed.BeginElse(); - + if_fixed.Else(); environment()->Push(BuildCloneShallowArray(context(), boilerplate, alloc_site_mode, @@ -250,7 +250,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { Handle<Code> FastCloneShallowArrayStub::GenerateCode() { CodeStubGraphBuilder<FastCloneShallowArrayStub> builder(this); LChunk* chunk = OptimizeGraph(builder.CreateGraph()); - return chunk->Codegen(Code::COMPILED_STUB); + return chunk->Codegen(); } @@ -359,11 +359,12 @@ HValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() { IfBuilder if_builder(this); - if_builder.BeginIf(array_length, graph()->GetConstant0(), Token::EQ); + if_builder.IfCompare(array_length, graph()->GetConstant0(), Token::EQ); + if_builder.Then(); // Nothing to do, just change the map. - if_builder.BeginElse(); + if_builder.Else(); HInstruction* elements = AddInstruction(new(zone) HLoadElements(js_array, js_array)); diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc index ad418d69cd..497dde54e7 100644 --- a/deps/v8/src/code-stubs.cc +++ b/deps/v8/src/code-stubs.cc @@ -67,7 +67,7 @@ void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) { } -int CodeStub::GetCodeKind() { +Code::Kind CodeStub::GetCodeKind() const { return Code::STUB; } @@ -98,7 +98,7 @@ Handle<Code> PlatformCodeStub::GenerateCode() { // Copy the generated code into a heap object. Code::Flags flags = Code::ComputeFlags( - static_cast<Code::Kind>(GetCodeKind()), + GetCodeKind(), GetICState(), GetExtraICState(), GetStubType(), @@ -308,7 +308,7 @@ void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { Factory* factory = isolate->factory(); Code::Flags flags = Code::ComputeFlags( - static_cast<Code::Kind>(GetCodeKind()), + GetCodeKind(), UNINITIALIZED); ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); Handle<Object> probe( diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h index 60c4fb9bd5..56b595583d 100644 --- a/deps/v8/src/code-stubs.h +++ b/deps/v8/src/code-stubs.h @@ -176,19 +176,19 @@ class CodeStub BASE_EMBEDDED { virtual Major MajorKey() = 0; virtual int MinorKey() = 0; - protected: - static bool CanUseFPRegisters(); - - // Generates the assembler code for the stub. - virtual Handle<Code> GenerateCode() = 0; - - // BinaryOpStub needs to override this. virtual InlineCacheState GetICState() { return UNINITIALIZED; } virtual Code::ExtraICState GetExtraICState() { return Code::kNoExtraICState; } + + protected: + static bool CanUseFPRegisters(); + + // Generates the assembler code for the stub. + virtual Handle<Code> GenerateCode() = 0; + virtual Code::StubType GetStubType() { return Code::NORMAL; } @@ -210,7 +210,7 @@ class CodeStub BASE_EMBEDDED { virtual void Activate(Code* code) { } // BinaryOpStub needs to override this. - virtual int GetCodeKind(); + virtual Code::Kind GetCodeKind() const; // Add the code to a specialized cache, specific to an individual // stub type. Please note, this method must add the code object to a @@ -249,7 +249,7 @@ class PlatformCodeStub : public CodeStub { // Retrieve the code for the stub. Generate the code if needed. virtual Handle<Code> GenerateCode(); - virtual int GetCodeKind() { return Code::STUB; } + virtual Code::Kind GetCodeKind() const { return Code::STUB; } virtual int GetStubFlags() { return -1; } protected: @@ -286,7 +286,7 @@ class HydrogenCodeStub : public CodeStub { // Retrieve the code for the stub. Generate the code if needed. virtual Handle<Code> GenerateCode() = 0; - virtual int GetCodeKind() { return Code::COMPILED_STUB; } + virtual Code::Kind GetCodeKind() const { return Code::STUB; } CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) { return isolate->code_stub_interface_descriptor(MajorKey()); @@ -606,7 +606,7 @@ class MathPowStub: public PlatformCodeStub { class ICStub: public PlatformCodeStub { public: explicit ICStub(Code::Kind kind) : kind_(kind) { } - virtual int GetCodeKind() { return kind_; } + virtual Code::Kind GetCodeKind() const { return kind_; } virtual InlineCacheState GetICState() { return MONOMORPHIC; } bool Describes(Code* code) { @@ -692,7 +692,7 @@ class StoreArrayLengthStub: public StoreICStub { class HandlerStub: public ICStub { public: explicit HandlerStub(Code::Kind kind) : ICStub(kind) { } - virtual int GetCodeKind() { return Code::STUB; } + virtual Code::Kind GetCodeKind() const { return Code::STUB; } virtual int GetStubFlags() { return kind(); } }; @@ -830,7 +830,7 @@ class BinaryOpStub: public PlatformCodeStub { // Entirely platform-specific methods are defined as static helper // functions in the <arch>/code-stubs-<arch>.cc files. - virtual int GetCodeKind() { return Code::BINARY_OP_IC; } + virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; } virtual InlineCacheState GetICState() { return BinaryOpIC::ToState(Max(left_type_, right_type_)); @@ -884,7 +884,7 @@ class ICCompareStub: public PlatformCodeStub { virtual CodeStub::Major MajorKey() { return CompareIC; } virtual int MinorKey(); - virtual int GetCodeKind() { return Code::COMPARE_IC; } + virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; } void GenerateSmis(MacroAssembler* masm); void GenerateNumbers(MacroAssembler* masm); @@ -1548,7 +1548,7 @@ class ToBooleanStub: public PlatformCodeStub { : tos_(tos), types_(types) { } void Generate(MacroAssembler* masm); - virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; } + virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } virtual void PrintName(StringStream* stream); virtual bool SometimesSetsUpAFrame() { return false; } diff --git a/deps/v8/src/codegen.cc b/deps/v8/src/codegen.cc index 90ab2b5a20..ff4003c1ef 100644 --- a/deps/v8/src/codegen.cc +++ b/deps/v8/src/codegen.cc @@ -106,10 +106,13 @@ Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, // Allocate and install the code. CodeDesc desc; + bool is_crankshafted = + Code::ExtractKindFromFlags(flags) == Code::OPTIMIZED_FUNCTION || + info->IsStub(); masm->GetCode(&desc); Handle<Code> code = - isolate->factory()->NewCode(desc, flags, masm->CodeObject()); - + isolate->factory()->NewCode(desc, flags, masm->CodeObject(), + false, is_crankshafted); if (!code.is_null()) { isolate->counters()->total_compiled_code_size()->Increment( code->instruction_size()); @@ -129,7 +132,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { if (print_code) { // Print the source code if available. FunctionLiteral* function = info->function(); - if (code->kind() != Code::COMPILED_STUB) { + if (code->kind() == Code::OPTIMIZED_FUNCTION) { Handle<Script> script = info->script(); if (!script->IsUndefined() && !script->source()->IsUndefined()) { PrintF("--- Raw source ---\n"); diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 184429b417..70ce6bc825 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -144,7 +144,11 @@ int CompilationInfo::num_heap_slots() const { Code::Flags CompilationInfo::flags() const { if (IsStub()) { - return Code::ComputeFlags(Code::COMPILED_STUB); + return Code::ComputeFlags(code_stub()->GetCodeKind(), + code_stub()->GetICState(), + code_stub()->GetExtraICState(), + Code::NORMAL, + 0); } else { return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); } @@ -421,7 +425,7 @@ OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() { Timer timer(this, &time_taken_to_codegen_); ASSERT(chunk_ != NULL); ASSERT(graph_ != NULL); - Handle<Code> optimized_code = chunk_->Codegen(Code::OPTIMIZED_FUNCTION); + Handle<Code> optimized_code = chunk_->Codegen(); if (optimized_code.is_null()) { info()->set_bailout_reason("code generation failed"); return AbortOptimization(); @@ -553,6 +557,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { isolate->factory()->NewSharedFunctionInfo( lit->name(), lit->materialized_literal_count(), + lit->is_generator(), info->code(), ScopeInfo::Create(info->scope(), info->zone())); @@ -1074,6 +1079,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, Handle<SharedFunctionInfo> result = FACTORY->NewSharedFunctionInfo(literal->name(), literal->materialized_literal_count(), + literal->is_generator(), info.code(), scope_info); SetFunctionInfo(result, literal, false, script); diff --git a/deps/v8/src/compiler.h b/deps/v8/src/compiler.h index 5e69661b4d..dae39db351 100644 --- a/deps/v8/src/compiler.h +++ b/deps/v8/src/compiler.h @@ -79,7 +79,7 @@ class CompilationInfo { Handle<JSFunction> closure() const { return closure_; } Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } Handle<Script> script() const { return script_; } - HydrogenCodeStub* code_stub() {return code_stub_; } + HydrogenCodeStub* code_stub() const {return code_stub_; } v8::Extension* extension() const { return extension_; } ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; } Handle<Context> context() const { return context_; } diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc index 1af736575b..92a2af23e4 100644 --- a/deps/v8/src/deoptimizer.cc +++ b/deps/v8/src/deoptimizer.cc @@ -1195,7 +1195,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, // reg = JSFunction context // - ASSERT(compiled_code_->kind() == Code::COMPILED_STUB); + ASSERT(compiled_code_->is_crankshafted() && + compiled_code_->kind() != Code::OPTIMIZED_FUNCTION); int major_key = compiled_code_->major_key(); CodeStubInterfaceDescriptor* descriptor = isolate_->code_stub_interface_descriptor(major_key); @@ -2133,7 +2134,7 @@ unsigned Deoptimizer::ComputeInputFrameSize() const { // size matches with the stack height we can compute based on the // environment at the OSR entry. The code for that his built into // the DoComputeOsrOutputFrame function for now. - } else if (compiled_code_->kind() != Code::COMPILED_STUB) { + } else if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { unsigned stack_slots = compiled_code_->stack_slots(); unsigned outgoing_size = ComputeOutgoingArgumentSize(); ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); diff --git a/deps/v8/src/disassembler.cc b/deps/v8/src/disassembler.cc index b01b443158..bbb1fb8d8e 100644 --- a/deps/v8/src/disassembler.cc +++ b/deps/v8/src/disassembler.cc @@ -332,8 +332,7 @@ int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) { // Called by Code::CodePrint. void Disassembler::Decode(FILE* f, Code* code) { Isolate* isolate = code->GetIsolate(); - int decode_size = (code->kind() == Code::OPTIMIZED_FUNCTION || - code->kind() == Code::COMPILED_STUB) + int decode_size = code->is_crankshafted() ? static_cast<int>(code->safepoint_table_offset()) : code->instruction_size(); // If there might be a back edge table, stop before reaching it. diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc index 5e2a2b1874..77d22006a6 100644 --- a/deps/v8/src/factory.cc +++ b/deps/v8/src/factory.cc @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2013 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -916,10 +916,11 @@ Handle<JSObject> Factory::NewExternal(void* value) { Handle<Code> Factory::NewCode(const CodeDesc& desc, Code::Flags flags, Handle<Object> self_ref, - bool immovable) { + bool immovable, + bool crankshafted) { CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CreateCode( - desc, flags, self_ref, immovable), + desc, flags, self_ref, immovable, crankshafted), Code); } @@ -1078,6 +1079,7 @@ void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) { Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<String> name, int number_of_literals, + bool is_generator, Handle<Code> code, Handle<ScopeInfo> scope_info) { Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name); @@ -1091,6 +1093,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( literals_array_size += JSFunction::kLiteralsPrefixSize; } shared->set_num_literals(literals_array_size); + if (is_generator) { + shared->set_instance_class_name(isolate()->heap()->Generator_string()); + } return shared; } diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h index 8695bcd520..b6bfa8ae46 100644 --- a/deps/v8/src/factory.h +++ b/deps/v8/src/factory.h @@ -347,7 +347,8 @@ class Factory { Handle<Code> NewCode(const CodeDesc& desc, Code::Flags flags, Handle<Object> self_reference, - bool immovable = false); + bool immovable = false, + bool crankshafted = false); Handle<Code> CopyCode(Handle<Code> code); @@ -454,6 +455,7 @@ class Factory { Handle<SharedFunctionInfo> NewSharedFunctionInfo( Handle<String> name, int number_of_literals, + bool is_generator, Handle<Code> code, Handle<ScopeInfo> scope_info); Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name); diff --git a/deps/v8/src/generator.js b/deps/v8/src/generator.js index d579928cba..481d4d37f8 100644 --- a/deps/v8/src/generator.js +++ b/deps/v8/src/generator.js @@ -39,18 +39,38 @@ // http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png function GeneratorObjectNext() { + if (!IS_GENERATOR(this)) { + throw MakeTypeError('incompatible_method_receiver', + ['[Generator].prototype.next', this]); + } + // TODO(wingo): Implement. } function GeneratorObjectSend(value) { + if (!IS_GENERATOR(this)) { + throw MakeTypeError('incompatible_method_receiver', + ['[Generator].prototype.send', this]); + } + // TODO(wingo): Implement. } function GeneratorObjectThrow(exn) { + if (!IS_GENERATOR(this)) { + throw MakeTypeError('incompatible_method_receiver', + ['[Generator].prototype.throw', this]); + } + // TODO(wingo): Implement. } function GeneratorObjectClose() { + if (!IS_GENERATOR(this)) { + throw MakeTypeError('incompatible_method_receiver', + ['[Generator].prototype.close', this]); + } + // TODO(wingo): Implement. } diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h index 28e50aa8bc..43d4a999cd 100644 --- a/deps/v8/src/heap-inl.h +++ b/deps/v8/src/heap-inl.h @@ -623,6 +623,13 @@ Isolate* Heap::isolate() { CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) +#define CALL_HEAP_FUNCTION_PASS_EXCEPTION(ISOLATE, FUNCTION_CALL) \ + CALL_AND_RETRY(ISOLATE, \ + FUNCTION_CALL, \ + return __object__, \ + return __maybe_object__) + + #ifdef DEBUG inline bool Heap::allow_allocation(bool new_state) { diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc index 453d985647..0c83c3aeb0 100644 --- a/deps/v8/src/heap.cc +++ b/deps/v8/src/heap.cc @@ -3752,7 +3752,8 @@ MaybeObject* Heap::AllocateExternalArray(int length, MaybeObject* Heap::CreateCode(const CodeDesc& desc, Code::Flags flags, Handle<Object> self_reference, - bool immovable) { + bool immovable, + bool crankshafted) { // Allocate ByteArray before the Code object, so that we do not risk // leaving uninitialized Code object (and breaking the heap). ByteArray* reloc_info; @@ -3796,6 +3797,7 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc, if (code->is_call_stub() || code->is_keyed_call_stub()) { code->set_check_type(RECEIVER_MAP_CHECK); } + code->set_is_crankshafted(crankshafted); code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); code->InitializeTypeFeedbackInfoNoWriteBarrier(undefined_value()); code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); @@ -4358,6 +4360,7 @@ MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) { MaybeObject* maybe_map = AllocateInitialMap(function); if (!maybe_map->To(&map)) return maybe_map; function->set_initial_map(map); + map->set_constructor(function); } ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); return AllocateJSObjectFromMap(map); diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h index 7b4b70d61c..66897ea862 100644 --- a/deps/v8/src/heap.h +++ b/deps/v8/src/heap.h @@ -268,7 +268,8 @@ namespace internal { V(infinity_string, "Infinity") \ V(minus_infinity_string, "-Infinity") \ V(hidden_stack_trace_string, "v8::hidden_stack_trace") \ - V(query_colon_string, "(?:)") + V(query_colon_string, "(?:)") \ + V(Generator_string, "Generator") // Forward declarations. class GCTracer; @@ -1141,7 +1142,8 @@ class Heap { MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc, Code::Flags flags, Handle<Object> self_reference, - bool immovable = false); + bool immovable = false, + bool crankshafted = false); MUST_USE_RESULT MaybeObject* CopyCode(Code* code); diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index 60a6912654..e7060beee6 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -648,6 +648,11 @@ int32_t HValue::GetInteger32Constant() { } +bool HValue::EqualsInteger32Constant(int32_t value) { + return IsInteger32Constant() && GetInteger32Constant() == value; +} + + void HValue::SetOperandAt(int index, HValue* value) { RegisterUse(index, value); InternalSetOperandAt(index, value); @@ -1393,15 +1398,11 @@ HValue* HBitwise::Canonicalize() { if (!representation().IsInteger32()) return this; // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; - if (left()->IsConstant() && - HConstant::cast(left())->HasInteger32Value() && - HConstant::cast(left())->Integer32Value() == nop_constant && + if (left()->EqualsInteger32Constant(nop_constant) && !right()->CheckFlag(kUint32)) { return right(); } - if (right()->IsConstant() && - HConstant::cast(right())->HasInteger32Value() && - HConstant::cast(right())->Integer32Value() == nop_constant && + if (right()->EqualsInteger32Constant(nop_constant) && !left()->CheckFlag(kUint32)) { return left(); } @@ -1422,17 +1423,37 @@ HValue* HBitNot::Canonicalize() { } -HValue* HAdd::Canonicalize() { - if (!representation().IsInteger32()) return this; - if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); +HValue* HArithmeticBinaryOperation::Canonicalize() { + if (representation().IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) { + ClearFlag(kCanOverflow); + } return this; } +static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) { + return arg1->representation().IsSpecialization() && + arg2->EqualsInteger32Constant(identity); +} + + +HValue* HAdd::Canonicalize() { + if (IsIdentityOperation(left(), right(), 0)) return left(); + if (IsIdentityOperation(right(), left(), 0)) return right(); + return HArithmeticBinaryOperation::Canonicalize(); +} + + HValue* HSub::Canonicalize() { - if (!representation().IsInteger32()) return this; - if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); - return this; + if (IsIdentityOperation(left(), right(), 0)) return left(); + return HArithmeticBinaryOperation::Canonicalize(); +} + + +HValue* HMul::Canonicalize() { + if (IsIdentityOperation(left(), right(), 1)) return left(); + if (IsIdentityOperation(right(), left(), 1)) return right(); + return HArithmeticBinaryOperation::Canonicalize(); } diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 6853dfe100..cfbcc135df 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -1001,6 +1001,7 @@ class HValue: public ZoneObject { bool IsInteger32Constant(); int32_t GetInteger32Constant(); + bool EqualsInteger32Constant(int32_t value); bool IsDefinedAfter(HBasicBlock* other) const; @@ -3328,10 +3329,6 @@ class HConstant: public HTemplateInstruction<0> { bool BooleanValue() const { return boolean_value_; } - bool IsUint32() { - return HasInteger32Value() && (Integer32Value() >= 0); - } - virtual intptr_t Hashcode() { if (has_int32_value_) { return static_cast<intptr_t>(int32_value_); @@ -3842,6 +3839,8 @@ class HArithmeticBinaryOperation: public HBinaryOperation { : representation(); } + virtual HValue* Canonicalize(); + private: virtual bool IsDeletable() const { return true; } }; @@ -4401,6 +4400,8 @@ class HMul: public HArithmeticBinaryOperation { virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); + virtual HValue* Canonicalize(); + // Only commutative if it is certain that not two objects are multiplicated. virtual bool IsCommutative() const { return !representation().IsTagged(); diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index 127d7a9aa1..e5270575e9 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -113,11 +113,10 @@ void HBasicBlock::AddInstruction(HInstruction* instr) { ASSERT(!IsStartBlock() || !IsFinished()); ASSERT(!instr->IsLinked()); ASSERT(!IsFinished()); - // Make sure that we never add instructions without knowing - // what the previous ast id is. - ASSERT(instr->IsSimulate() || instr->IsGoto() || - !last_environment()->previous_ast_id().IsNone()); + if (first_ == NULL) { + ASSERT(last_environment() != NULL); + ASSERT(!last_environment()->ast_id().IsNone()); HBlockEntry* entry = new(zone()) HBlockEntry(); entry->InitializeAsFirst(this); first_ = last_ = entry; @@ -184,7 +183,9 @@ void HBasicBlock::Finish(HControlInstruction* end) { } -void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { +void HBasicBlock::Goto(HBasicBlock* block, + FunctionState* state, + bool add_simulate) { bool drop_extra = state != NULL && state->inlining_kind() == DROP_EXTRA_ON_RETURN; @@ -193,7 +194,7 @@ void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { last_environment_ = last_environment()->DiscardInlined(drop_extra); } - AddSimulate(BailoutId::None()); + if (add_simulate) AddSimulate(BailoutId::None()); HGoto* instr = new(zone()) HGoto(block); Finish(instr); } @@ -215,12 +216,10 @@ void HBasicBlock::AddLeaveInlined(HValue* return_value, } -void HBasicBlock::SetInitialEnvironment(HEnvironment* env, - BailoutId previous_ast_id) { +void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { ASSERT(!HasEnvironment()); ASSERT(first() == NULL); UpdateEnvironment(env); - env->set_previous_ast_id(previous_ast_id); } @@ -236,11 +235,7 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) { predecessor->last_environment()->closure()->shared() ->VerifyBailoutId(ast_id))); simulate->set_ast_id(ast_id); - } - HEnvironment* last_environment = this->last_environment(); - ASSERT(last_environment || IsFinished()); - if (last_environment != NULL) { - last_environment->set_previous_ast_id(ast_id); + predecessor->last_environment()->set_ast_id(ast_id); } } @@ -301,9 +296,7 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { } } else if (!HasEnvironment() && !IsFinished()) { ASSERT(!IsLoopHeader()); - HEnvironment* new_env = pred->last_environment()->Copy(); - SetInitialEnvironment(new_env, - pred->last_environment()->previous_ast_id()); + SetInitialEnvironment(pred->last_environment()->Copy()); } predecessors_.Add(pred, zone()); @@ -553,6 +546,18 @@ void HGraph::Verify(bool do_full_verify) const { HPhi* phi = block->phis()->at(j); phi->Verify(); } + + // Check that all join blocks have predecessors that end with an + // unconditional goto and agree on their environment node id. + if (block->predecessors()->length() >= 2) { + BailoutId id = + block->predecessors()->first()->last_environment()->ast_id(); + for (int k = 0; k < block->predecessors()->length(); k++) { + HBasicBlock* predecessor = block->predecessors()->at(k); + ASSERT(predecessor->end()->IsGoto()); + ASSERT(predecessor->last_environment()->ast_id() == id); + } + } } // Check special property of first block to have no predecessors. @@ -639,25 +644,24 @@ DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) : builder_(builder), - finished_(false), - id_(builder->current_block()->last_environment()->previous_ast_id()) { + finished_(false) { HEnvironment* env = builder->environment(); - failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); - merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); + failure_block_ = builder->CreateBasicBlock(env->Copy()); + merge_block_ = builder->CreateBasicBlock(env->Copy()); } HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { HEnvironment* env = builder_->environment(); - HIsNilAndBranch* compare = - new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); - HBasicBlock* success_block = - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); - HBasicBlock* failure_block = - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); + HCompareObjectEqAndBranch* compare = + new(zone()) HCompareObjectEqAndBranch( + value, + builder_->graph()->GetConstantUndefined()); + HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy()); + HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy()); compare->SetSuccessorAt(0, failure_block); compare->SetSuccessorAt(1, success_block); - failure_block->Goto(failure_block_); + failure_block->GotoNoSimulate(failure_block_); builder_->current_block()->Finish(compare); builder_->set_current_block(success_block); return compare; @@ -671,13 +675,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, HCompareIDAndBranch* compare = new(zone()) HCompareIDAndBranch(left, right, op); compare->AssumeRepresentation(Representation::Integer32()); - HBasicBlock* success_block = - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); - HBasicBlock* failure_block = - builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); + HBasicBlock* success_block = builder_->CreateBasicBlock(env->Copy()); + HBasicBlock* failure_block = builder_->CreateBasicBlock(env->Copy()); compare->SetSuccessorAt(0, success_block); compare->SetSuccessorAt(1, failure_block); - failure_block->Goto(failure_block_); + failure_block->GotoNoSimulate(failure_block_); builder_->current_block()->Finish(compare); builder_->set_current_block(success_block); return compare; @@ -692,11 +694,11 @@ HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, void HGraphBuilder::CheckBuilder::End() { ASSERT(!finished_); - builder_->current_block()->Goto(merge_block_); - failure_block_->SetJoinId(id_); - failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); + builder_->current_block()->GotoNoSimulate(merge_block_); + if (failure_block_->HasPredecessor()) { + failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); + } builder_->set_current_block(merge_block_); - merge_block_->SetJoinId(id_); finished_ = true; } @@ -706,19 +708,51 @@ HConstant* HGraph::GetInvalidContext() { } -HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) +HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) : builder_(builder), + position_(position), finished_(false), + did_then_(false), did_else_(false), - id_(builder->current_block()->last_environment()->previous_ast_id()) { + deopt_then_(false), + deopt_else_(false), + did_and_(false), + did_or_(false), + captured_(false), + needs_compare_(true), + split_edge_merge_block_(NULL) { HEnvironment* env = builder->environment(); - first_true_block_ = builder->CreateBasicBlock(env->Copy(), id_); + first_true_block_ = builder->CreateBasicBlock(env->Copy()); last_true_block_ = NULL; - first_false_block_ = builder->CreateBasicBlock(env->Copy(), id_); + first_false_block_ = builder->CreateBasicBlock(env->Copy()); } -HInstruction* HGraphBuilder::IfBuilder::BeginIf( +HGraphBuilder::IfBuilder::IfBuilder( + HGraphBuilder* builder, + HIfContinuation* continuation) + : builder_(builder), + position_(RelocInfo::kNoPosition), + finished_(false), + did_then_(false), + did_else_(false), + deopt_then_(false), + deopt_else_(false), + did_and_(false), + did_or_(false), + captured_(false), + needs_compare_(false), + first_true_block_(NULL), + first_false_block_(NULL), + split_edge_merge_block_(NULL), + merge_block_(NULL) { + continuation->Continue(&first_true_block_, + &first_false_block_, + &position_); +} + + +HInstruction* HGraphBuilder::IfBuilder::IfCompare( HValue* left, HValue* right, Token::Value token, @@ -728,58 +762,148 @@ HInstruction* HGraphBuilder::IfBuilder::BeginIf( compare->set_observed_input_representation(input_representation, input_representation); compare->ChangeRepresentation(input_representation); - compare->SetSuccessorAt(0, first_true_block_); - compare->SetSuccessorAt(1, first_false_block_); - builder_->current_block()->Finish(compare); - builder_->set_current_block(first_true_block_); + AddCompare(compare); return compare; } -HInstruction* HGraphBuilder::IfBuilder::BeginIfObjectsEqual( - HValue* left, - HValue* right) { - HCompareObjectEqAndBranch* compare = - new(zone()) HCompareObjectEqAndBranch(left, right); - compare->SetSuccessorAt(0, first_true_block_); - compare->SetSuccessorAt(1, first_false_block_); - builder_->current_block()->Finish(compare); - builder_->set_current_block(first_true_block_); +HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, + Handle<Map> map) { + HCompareMap* compare = + new(zone()) HCompareMap(left, map, + first_true_block_, first_false_block_); + AddCompare(compare); return compare; } -HInstruction* HGraphBuilder::IfBuilder::BeginIfMapEquals(HValue* value, - Handle<Map> map) { - HCompareMap* compare = new(zone()) - HCompareMap(value, map, first_true_block_, first_false_block_); +void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { + if (split_edge_merge_block_ != NULL) { + HEnvironment* env = first_false_block_->last_environment(); + HBasicBlock* split_edge = + builder_->CreateBasicBlock(env->Copy()); + if (did_or_) { + compare->SetSuccessorAt(0, split_edge); + compare->SetSuccessorAt(1, first_false_block_); + } else { + compare->SetSuccessorAt(0, first_true_block_); + compare->SetSuccessorAt(1, split_edge); + } + split_edge->GotoNoSimulate(split_edge_merge_block_); + } else { + compare->SetSuccessorAt(0, first_true_block_); + compare->SetSuccessorAt(1, first_false_block_); + } builder_->current_block()->Finish(compare); + needs_compare_ = false; +} + + +void HGraphBuilder::IfBuilder::Or() { + ASSERT(!did_and_); + did_or_ = true; + HEnvironment* env = first_false_block_->last_environment(); + if (split_edge_merge_block_ == NULL) { + split_edge_merge_block_ = + builder_->CreateBasicBlock(env->Copy()); + first_true_block_->GotoNoSimulate(split_edge_merge_block_); + first_true_block_ = split_edge_merge_block_; + } + builder_->set_current_block(first_false_block_); + first_false_block_ = builder_->CreateBasicBlock(env->Copy()); +} + + +void HGraphBuilder::IfBuilder::And() { + ASSERT(!did_or_); + did_and_ = true; + HEnvironment* env = first_false_block_->last_environment(); + if (split_edge_merge_block_ == NULL) { + split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy()); + first_false_block_->GotoNoSimulate(split_edge_merge_block_); + first_false_block_ = split_edge_merge_block_; + } + builder_->set_current_block(first_true_block_); + first_true_block_ = builder_->CreateBasicBlock(env->Copy()); +} + + +void HGraphBuilder::IfBuilder::CaptureContinuation( + HIfContinuation* continuation) { + ASSERT(!finished_); + ASSERT(!captured_); + HBasicBlock* true_block = last_true_block_ == NULL + ? first_true_block_ + : last_true_block_; + HBasicBlock* false_block = + did_else_ ? builder_->current_block() : first_false_block_; + continuation->Capture(true_block, false_block, position_); + captured_ = true; + End(); +} + + +void HGraphBuilder::IfBuilder::Then() { + ASSERT(!captured_); + ASSERT(!finished_); + did_then_ = true; + if (needs_compare_) { + // Handle if's without any expressions, they jump directly to the "else" + // branch. + builder_->current_block()->GotoNoSimulate(first_false_block_); + first_true_block_ = NULL; + } builder_->set_current_block(first_true_block_); - return compare; } -void HGraphBuilder::IfBuilder::BeginElse() { +void HGraphBuilder::IfBuilder::Else() { + ASSERT(did_then_); + ASSERT(!captured_); + ASSERT(!finished_); last_true_block_ = builder_->current_block(); - ASSERT(!last_true_block_->IsFinished()); + ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); builder_->set_current_block(first_false_block_); did_else_ = true; } +void HGraphBuilder::IfBuilder::Deopt() { + ASSERT(!(did_then_ ^ did_else_)); + HBasicBlock* block = builder_->current_block(); + block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); + if (did_else_) { + first_false_block_ = NULL; + did_else_ = false; + } else { + first_true_block_ = NULL; + } +} + + void HGraphBuilder::IfBuilder::End() { - ASSERT(!finished_); - if (!did_else_) BeginElse(); - ASSERT(!last_true_block_->IsFinished()); - HBasicBlock* last_false_block = builder_->current_block(); - ASSERT(!last_false_block->IsFinished()); - HEnvironment* merge_env = - last_true_block_->last_environment()->CopyWithoutHistory(); - merge_block_ = builder_->CreateBasicBlock(merge_env, id_); - last_true_block_->Goto(merge_block_); - last_false_block->Goto(merge_block_); - merge_block_->SetJoinId(id_); - builder_->set_current_block(merge_block_); + if (!captured_) { + ASSERT(did_then_); + if (!did_else_) { + last_true_block_ = builder_->current_block(); + } + if (first_true_block_ == NULL) { + // Deopt on true. Nothing to do, just continue the else block. + } else if (first_false_block_ == NULL) { + builder_->set_current_block(last_true_block_); + } else { + HEnvironment* merge_env = last_true_block_->last_environment()->Copy(); + merge_block_ = builder_->CreateBasicBlock(merge_env); + ASSERT(!finished_); + if (!did_else_) Else(); + ASSERT(!last_true_block_->IsFinished()); + HBasicBlock* last_false_block = builder_->current_block(); + ASSERT(!last_false_block->IsFinished()); + last_true_block_->GotoNoSimulate(merge_block_); + last_false_block->GotoNoSimulate(merge_block_); + builder_->set_current_block(merge_block_); + } + } finished_ = true; } @@ -790,9 +914,8 @@ HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, : builder_(builder), context_(context), direction_(direction), - id_(builder->current_block()->last_environment()->previous_ast_id()), finished_(false) { - header_block_ = builder->CreateLoopHeaderBlock(id_); + header_block_ = builder->CreateLoopHeaderBlock(); body_block_ = NULL; exit_block_ = NULL; } @@ -809,12 +932,12 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody( phi_->AddInput(initial); phi_->ChangeRepresentation(Representation::Integer32()); env->Push(initial); - builder_->current_block()->Goto(header_block_); + builder_->current_block()->GotoNoSimulate(header_block_); HEnvironment* body_env = env->Copy(); HEnvironment* exit_env = env->Copy(); - body_block_ = builder_->CreateBasicBlock(body_env, id_); - exit_block_ = builder_->CreateBasicBlock(exit_env, id_); + body_block_ = builder_->CreateBasicBlock(body_env); + exit_block_ = builder_->CreateBasicBlock(exit_env); // Remove the phi from the expression stack body_env->Pop(); @@ -863,9 +986,8 @@ void HGraphBuilder::LoopBuilder::EndBody() { // Push the new increment value on the expression stack to merge into the phi. builder_->environment()->Push(increment_); - builder_->current_block()->Goto(header_block_); + builder_->current_block()->GotoNoSimulate(header_block_); header_block_->loop_information()->RegisterBackEdge(body_block_); - header_block_->SetJoinId(id_); builder_->set_current_block(exit_block_); // Pop the phi from the expression stack @@ -900,7 +1022,6 @@ void HGraphBuilder::AddSimulate(BailoutId id, ASSERT(current_block() != NULL); ASSERT(no_side_effects_scope_count_ == 0); current_block()->AddSimulate(id, removable); - environment()->set_previous_ast_id(id); } @@ -935,23 +1056,37 @@ HReturn* HGraphBuilder::AddReturn(HValue* value) { } -HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env, - BailoutId previous_ast_id) { +HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { HBasicBlock* b = graph()->CreateBasicBlock(); - b->SetInitialEnvironment(env, previous_ast_id); + b->SetInitialEnvironment(env); return b; } -HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock(BailoutId previous_ast_id) { +HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { HBasicBlock* header = graph()->CreateBasicBlock(); HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); - header->SetInitialEnvironment(entry_env, previous_ast_id); + header->SetInitialEnvironment(entry_env); header->AttachLoopInformation(); return header; } +HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { + HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); + AddInstruction(check); + return check; +} + + +HValue* HGraphBuilder::BuildCheckMap(HValue* obj, + Handle<Map> map) { + HCheckMaps* check = new(zone()) HCheckMaps(obj, map, zone()); + AddInstruction(check); + return check; +} + + HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( HValue* external_elements, HValue* checked_key, @@ -1049,14 +1184,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, Zone* zone = this->zone(); IfBuilder length_checker(this); - length_checker.BeginIf(length, key, Token::EQ); + length_checker.IfCompare(length, key, Token::EQ); + length_checker.Then(); HValue* current_capacity = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); IfBuilder capacity_checker(this); - capacity_checker.BeginIf(length, current_capacity, Token::EQ); + capacity_checker.IfCompare(length, current_capacity, Token::EQ); + capacity_checker.Then(); HValue* context = environment()->LookupContext(); @@ -1068,7 +1205,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, new_capacity); environment()->Push(new_elements); - capacity_checker.BeginElse(); + capacity_checker.Else(); environment()->Push(elements); capacity_checker.End(); @@ -1088,7 +1225,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, length_store->SetGVNFlag(kChangesArrayLengths); } - length_checker.BeginElse(); + length_checker.Else(); AddBoundsCheck(key, length, ALLOW_SMI_KEY); environment()->Push(elements); @@ -1108,19 +1245,19 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, IfBuilder cow_checker(this); - cow_checker.BeginIfMapEquals(elements, - Handle<Map>(heap->fixed_cow_array_map())); + cow_checker.IfCompareMap(elements, + Handle<Map>(heap->fixed_cow_array_map())); + cow_checker.Then(); HValue* capacity = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); HValue* new_elements = BuildGrowElementsCapacity(object, elements, - kind, length, - capacity); + kind, length, capacity); environment()->Push(new_elements); - cow_checker.BeginElse(); + cow_checker.Else(); environment()->Push(elements); @@ -1175,11 +1312,13 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( HValue* checked_key = NULL; if (IsExternalArrayElementsKind(elements_kind)) { if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { + NoObservableSideEffectsScope no_effects(this); HLoadExternalArrayPointer* external_elements = new(zone) HLoadExternalArrayPointer(elements); AddInstruction(external_elements); IfBuilder length_checker(this); - length_checker.BeginIf(key, length, Token::LT); + length_checker.IfCompare(key, length, Token::LT); + length_checker.Then(); CheckBuilder negative_checker(this); HValue* bounds_check = negative_checker.CheckIntegerCompare( key, graph()->GetConstant0(), Token::GTE); @@ -1216,7 +1355,11 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( elements = BuildCheckForCapacityGrow(object, elements, elements_kind, length, key, is_js_array); - checked_key = key; + if (!key->type().IsSmi()) { + checked_key = AddInstruction(new(zone) HCheckSmiOrInt32(key)); + } else { + checked_key = key; + } } else { checked_key = AddBoundsCheck( key, length, ALLOW_SMI_KEY, checked_index_representation); @@ -1307,8 +1450,7 @@ void HGraphBuilder::BuildInitializeElements(HValue* elements, HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, ElementsKind kind, HValue* capacity) { - HValue* new_elements = - BuildAllocateElements(context, kind, capacity); + HValue* new_elements = BuildAllocateElements(context, kind, capacity); BuildInitializeElements(new_elements, kind, capacity); return new_elements; } @@ -1684,9 +1826,9 @@ HGraph::HGraph(CompilationInfo* info) start_environment_ = new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); } + start_environment_->set_ast_id(BailoutId::FunctionEntry()); entry_block_ = CreateBasicBlock(); - entry_block_->SetInitialEnvironment(start_environment_, - BailoutId::FunctionEntry()); + entry_block_->SetInitialEnvironment(start_environment_); } @@ -3839,8 +3981,8 @@ bool Uint32Analysis::CheckPhiOperands(HPhi* phi) { HValue* operand = phi->OperandAt(j); if (!operand->CheckFlag(HInstruction::kUint32)) { // Lazyly mark constants that fit into uint32 range with kUint32 flag. - if (operand->IsConstant() && - HConstant::cast(operand)->IsUint32()) { + if (operand->IsInteger32Constant() && + operand->GetInteger32Constant() >= 0) { operand->SetFlag(HInstruction::kUint32); continue; } @@ -4099,6 +4241,22 @@ void EffectContext::ReturnControl(HControlInstruction* instr, } +void EffectContext::ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id) { + HBasicBlock* true_branch = NULL; + HBasicBlock* false_branch = NULL; + continuation->Continue(&true_branch, &false_branch, NULL); + if (!continuation->IsTrueReachable()) { + owner()->set_current_block(false_branch); + } else if (!continuation->IsFalseReachable()) { + owner()->set_current_block(true_branch); + } else { + HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); + owner()->set_current_block(join); + } +} + + void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { ASSERT(!instr->IsControlInstruction()); if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { @@ -4132,6 +4290,29 @@ void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { } +void ValueContext::ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id) { + HBasicBlock* materialize_true = NULL; + HBasicBlock* materialize_false = NULL; + continuation->Continue(&materialize_true, &materialize_false, NULL); + if (continuation->IsTrueReachable()) { + owner()->set_current_block(materialize_true); + owner()->Push(owner()->graph()->GetConstantTrue()); + owner()->set_current_block(materialize_true); + } + if (continuation->IsFalseReachable()) { + owner()->set_current_block(materialize_false); + owner()->Push(owner()->graph()->GetConstantFalse()); + owner()->set_current_block(materialize_false); + } + if (continuation->TrueAndFalseReachable()) { + HBasicBlock* join = + owner()->CreateJoin(materialize_true, materialize_false, ast_id); + owner()->set_current_block(join); + } +} + + void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { ASSERT(!instr->IsControlInstruction()); HOptimizedGraphBuilder* builder = owner(); @@ -4160,6 +4341,21 @@ void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { } +void TestContext::ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id) { + HBasicBlock* true_branch = NULL; + HBasicBlock* false_branch = NULL; + continuation->Continue(&true_branch, &false_branch, NULL); + if (continuation->IsTrueReachable()) { + true_branch->Goto(if_true(), owner()->function_state()); + } + if (continuation->IsFalseReachable()) { + false_branch->Goto(if_false(), owner()->function_state()); + } + owner()->set_current_block(NULL); +} + + void TestContext::BuildBranch(HValue* value) { // We expect the graph to be in edge-split form: there is no edge that // connects a branch node to a join node. We conservatively ensure that @@ -4296,8 +4492,7 @@ bool HOptimizedGraphBuilder::BuildGraph() { // values (but not instructions), present in the initial environment and // not replayed by the Lithium translation. HEnvironment* initial_env = environment()->CopyWithoutHistory(); - HBasicBlock* body_entry = CreateBasicBlock(initial_env, - BailoutId::FunctionEntry()); + HBasicBlock* body_entry = CreateBasicBlock(initial_env); current_block()->Goto(body_entry); body_entry->SetJoinId(BailoutId::FunctionEntry()); set_current_block(body_entry); @@ -5541,7 +5736,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { ASSERT(current_block()->HasPredecessor()); ASSERT(current_block() != NULL); bool osr_entry = PreProcessOsrEntry(stmt); - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); current_block()->Goto(loop_entry); set_current_block(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry); @@ -5584,7 +5779,7 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { ASSERT(current_block()->HasPredecessor()); ASSERT(current_block() != NULL); bool osr_entry = PreProcessOsrEntry(stmt); - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); current_block()->Goto(loop_entry); set_current_block(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry); @@ -5631,7 +5826,7 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { } ASSERT(current_block() != NULL); bool osr_entry = PreProcessOsrEntry(stmt); - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); current_block()->Goto(loop_entry); set_current_block(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry); @@ -5726,7 +5921,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { HForInCacheArray::cast(index_cache)); bool osr_entry = PreProcessOsrEntry(stmt); - HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); + HBasicBlock* loop_entry = CreateLoopHeaderBlock(); current_block()->Goto(loop_entry); set_current_block(loop_entry); if (osr_entry) graph()->set_osr_loop_entry(loop_entry); @@ -6804,7 +6999,6 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { true, // is_store &has_side_effects); Push(value); - ASSERT(has_side_effects); // Stores always have side effects. AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); return ast_context()->ReturnValue(Pop()); } @@ -8279,7 +8473,6 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, AddSimulate(return_id); current_block()->UpdateEnvironment(inner_env); - inner_env->set_previous_ast_id(BailoutId::FunctionEntry()); ZoneList<HValue*>* arguments_values = NULL; // If the function uses arguments copy current arguments values @@ -8547,6 +8740,18 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( return true; } break; + case kStringFromCharCode: + if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { + AddCheckConstantFunction(expr->holder(), receiver, receiver_map); + HValue* argument = Pop(); + HValue* context = environment()->LookupContext(); + Drop(1); // Receiver. + HInstruction* result = + HStringCharFromCode::New(zone(), context, argument); + ast_context()->ReturnInstruction(result, expr->id()); + return true; + } + break; case kMathExp: if (!FLAG_fast_math) break; // Fall through if FLAG_fast_math. @@ -8600,9 +8805,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( } else if (exponent == 2.0) { result = HMul::New(zone(), context, left, left); } - } else if (right->IsConstant() && - HConstant::cast(right)->HasInteger32Value() && - HConstant::cast(right)->Integer32Value() == 2) { + } else if (right->EqualsInteger32Constant(2)) { result = HMul::New(zone(), context, left, left); } @@ -9160,7 +9363,6 @@ void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { case Token::DELETE: return VisitDelete(expr); case Token::VOID: return VisitVoid(expr); case Token::TYPEOF: return VisitTypeof(expr); - case Token::ADD: return VisitAdd(expr); case Token::SUB: return VisitSub(expr); case Token::BIT_NOT: return VisitBitNot(expr); case Token::NOT: return VisitNot(expr); @@ -9218,21 +9420,6 @@ void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { } -void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { - CHECK_ALIVE(VisitForValue(expr->expression())); - HValue* value = Pop(); - HValue* context = environment()->LookupContext(); - HInstruction* instr = - HMul::New(zone(), context, value, graph()->GetConstant1()); - if (instr->IsBinaryOperation()) { - // Since we don't have type feedback, we must be cautious/pessimistic. - HBinaryOperation::cast(instr)->set_observed_input_representation( - Representation::Tagged(), Representation::Tagged()); - } - return ast_context()->ReturnInstruction(instr, expr->id()); -} - - void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { CHECK_ALIVE(VisitForValue(expr->expression())); HValue* value = Pop(); @@ -11033,7 +11220,6 @@ HEnvironment::HEnvironment(HEnvironment* outer, pop_count_(0), push_count_(0), ast_id_(BailoutId::None()), - previous_ast_id_(BailoutId::None()), zone_(zone) { Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); } @@ -11050,7 +11236,6 @@ HEnvironment::HEnvironment(Zone* zone, int parameter_count) pop_count_(0), push_count_(0), ast_id_(BailoutId::None()), - previous_ast_id_(BailoutId::None()), zone_(zone) { Initialize(parameter_count, 0, 0); } @@ -11067,7 +11252,6 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) pop_count_(0), push_count_(0), ast_id_(other->ast_id()), - previous_ast_id_(BailoutId::None()), zone_(zone) { Initialize(other); } @@ -11088,7 +11272,6 @@ HEnvironment::HEnvironment(HEnvironment* outer, pop_count_(0), push_count_(0), ast_id_(BailoutId::None()), - previous_ast_id_(BailoutId::None()), zone_(zone) { } diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h index 3dbca3c3ea..809942b065 100644 --- a/deps/v8/src/hydrogen.h +++ b/deps/v8/src/hydrogen.h @@ -108,7 +108,7 @@ class HBasicBlock: public ZoneObject { bool Dominates(HBasicBlock* other) const; int LoopNestingDepth() const; - void SetInitialEnvironment(HEnvironment* env, BailoutId previous_id); + void SetInitialEnvironment(HEnvironment* env); void ClearEnvironment() { last_environment_ = NULL; } bool HasEnvironment() const { return last_environment_ != NULL; } void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } @@ -125,7 +125,12 @@ class HBasicBlock: public ZoneObject { void Finish(HControlInstruction* last); void FinishExit(HControlInstruction* instruction); - void Goto(HBasicBlock* block, FunctionState* state = NULL); + void Goto(HBasicBlock* block, + FunctionState* state = NULL, + bool add_simulate = true); + void GotoNoSimulate(HBasicBlock* block) { + Goto(block, NULL, false); + } int PredecessorIndexOf(HBasicBlock* predecessor) const; void AddSimulate(BailoutId ast_id, @@ -484,8 +489,6 @@ class HEnvironment: public ZoneObject { BailoutId ast_id() const { return ast_id_; } void set_ast_id(BailoutId id) { ast_id_ = id; } - BailoutId previous_ast_id() const { return previous_ast_id_; } - void set_previous_ast_id(BailoutId id) { previous_ast_id_ = id; } HEnterInlined* entry() const { return entry_; } void set_entry(HEnterInlined* entry) { entry_ = entry; } @@ -647,7 +650,6 @@ class HEnvironment: public ZoneObject { int pop_count_; int push_count_; BailoutId ast_id_; - BailoutId previous_ast_id_; Zone* zone_; }; @@ -678,6 +680,9 @@ enum ArgumentsAllowedFlag { ARGUMENTS_ALLOWED }; + +class HIfContinuation; + // This class is not BASE_EMBEDDED because our inlining implementation uses // new and delete. class AstContext { @@ -703,6 +708,13 @@ class AstContext { // expressions. virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id) = 0; + // Finishes the current basic block and materialize a boolean for + // value context, nothing for effect, generate a branch for test context. + // Call this function in tail position in the Visit functions for + // expressions that use an IfBuilder. + virtual void ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id) = 0; + void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; } bool is_for_typeof() { return for_typeof_; } @@ -738,6 +750,8 @@ class EffectContext: public AstContext { virtual void ReturnValue(HValue* value); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); + virtual void ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id); }; @@ -751,6 +765,8 @@ class ValueContext: public AstContext { virtual void ReturnValue(HValue* value); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); + virtual void ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id); bool arguments_allowed() { return flag_ == ARGUMENTS_ALLOWED; } @@ -776,6 +792,8 @@ class TestContext: public AstContext { virtual void ReturnValue(HValue* value); virtual void ReturnInstruction(HInstruction* instr, BailoutId ast_id); virtual void ReturnControl(HControlInstruction* instr, BailoutId ast_id); + virtual void ReturnContinuation(HIfContinuation* continuation, + BailoutId ast_id); static TestContext* cast(AstContext* context) { ASSERT(context->IsTest()); @@ -863,6 +881,45 @@ class FunctionState { }; +class HIfContinuation { + public: + HIfContinuation() { continuation_captured_ = false; } + ~HIfContinuation() { ASSERT(!continuation_captured_); } + + void Capture(HBasicBlock* true_branch, + HBasicBlock* false_branch, + int position) { + ASSERT(!continuation_captured_); + ASSERT(true_branch != NULL || false_branch != NULL); + true_branch_ = true_branch; + false_branch_ = false_branch; + position_ = position; + continuation_captured_ = true; + } + + void Continue(HBasicBlock** true_branch, + HBasicBlock** false_branch, + int* position) { + ASSERT(continuation_captured_); + *true_branch = true_branch_; + *false_branch = false_branch_; + if (position != NULL) *position = position_; + continuation_captured_ = false; + } + + bool IsTrueReachable() { return true_branch_ != NULL; } + bool IsFalseReachable() { return false_branch_ != NULL; } + bool TrueAndFalseReachable() { + return IsTrueReachable() || IsFalseReachable(); + } + + bool continuation_captured_; + HBasicBlock* true_branch_; + HBasicBlock* false_branch_; + int position_; +}; + + class HGraphBuilder { public: explicit HGraphBuilder(CompilationInfo* info) @@ -906,9 +963,11 @@ class HGraphBuilder { protected: virtual bool BuildGraph() = 0; - HBasicBlock* CreateBasicBlock(HEnvironment* envy, - BailoutId previous_ast_id); - HBasicBlock* CreateLoopHeaderBlock(BailoutId previous_ast_id); + HBasicBlock* CreateBasicBlock(HEnvironment* env); + HBasicBlock* CreateLoopHeaderBlock(); + + HValue* BuildCheckNonSmi(HValue* object); + HValue* BuildCheckMap(HValue* obj, Handle<Map> map); // Building common constructs HInstruction* BuildExternalArrayElementAccess( @@ -973,37 +1032,127 @@ class HGraphBuilder { bool finished_; HBasicBlock* failure_block_; HBasicBlock* merge_block_; - BailoutId id_; }; class IfBuilder { public: - explicit IfBuilder(HGraphBuilder* builder); + explicit IfBuilder(HGraphBuilder* builder, + int position = RelocInfo::kNoPosition); + IfBuilder(HGraphBuilder* builder, + HIfContinuation* continuation); + ~IfBuilder() { if (!finished_) End(); } - HInstruction* BeginIf( + HInstruction* IfCompare( HValue* left, HValue* right, Token::Value token, Representation input_representation = Representation::Integer32()); - HInstruction* BeginIfObjectsEqual(HValue* left, HValue* right); - HInstruction* BeginIfMapEquals(HValue* value, Handle<Map> map); - void BeginElse(); + + HInstruction* IfCompareMap(HValue* left, Handle<Map> map); + + template<class Condition> + HInstruction* If(HValue *p) { + HControlInstruction* compare = new(zone()) Condition(p); + AddCompare(compare); + return compare; + } + + template<class Condition, class P2> + HInstruction* If(HValue* p1, P2 p2) { + HControlInstruction* compare = new(zone()) Condition(p1, p2); + AddCompare(compare); + return compare; + } + + template<class Condition> + HInstruction* OrIfCompare( + HValue* p1, + HValue* p2, + Token::Value token, + Representation input_representation = Representation::Integer32()) { + Or(); + return IfCompare(p1, p2, token, input_representation); + } + + HInstruction* OrIfCompareMap(HValue* left, Handle<Map> map) { + Or(); + return IfCompareMap(left, map); + } + + template<class Condition> + HInstruction* OrIf(HValue *p) { + Or(); + return If<Condition>(p); + } + + template<class Condition, class P2> + HInstruction* OrIf(HValue* p1, P2 p2) { + Or(); + return If<Condition>(p1, p2); + } + + template<class Condition> + HInstruction* AndIfCompare( + HValue* p1, + HValue* p2, + Token::Value token, + Representation input_representation = Representation::Integer32()) { + And(); + return IfCompare(p1, p2, token, input_representation); + } + + HInstruction* AndIfCompareMap(HValue* left, Handle<Map> map) { + And(); + return IfCompareMap(left, map); + } + + template<class Condition> + HInstruction* AndIf(HValue *p) { + And(); + return If<Condition>(p); + } + + template<class Condition, class P2> + HInstruction* AndIf(HValue* p1, P2 p2) { + And(); + return If<Condition>(p1, p2); + } + + void Or(); + void And(); + + void CaptureContinuation(HIfContinuation* continuation); + + void Then(); + void Else(); void End(); + void Deopt(); + private: + void AddCompare(HControlInstruction* compare); + Zone* zone() { return builder_->zone(); } HGraphBuilder* builder_; - bool finished_; - bool did_else_; + int position_; + bool finished_ : 1; + bool did_then_ : 1; + bool did_else_ : 1; + bool deopt_then_ : 1; + bool deopt_else_ : 1; + bool did_and_ : 1; + bool did_or_ : 1; + bool captured_ : 1; + bool needs_compare_ : 1; HBasicBlock* first_true_block_; HBasicBlock* last_true_block_; HBasicBlock* first_false_block_; + HBasicBlock* split_edge_merge_block_; HBasicBlock* merge_block_; - BailoutId id_; }; class LoopBuilder { @@ -1040,7 +1189,6 @@ class HGraphBuilder { HBasicBlock* body_block_; HBasicBlock* exit_block_; Direction direction_; - BailoutId id_; bool finished_; }; @@ -1267,7 +1415,6 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { void VisitDelete(UnaryOperation* expr); void VisitVoid(UnaryOperation* expr); void VisitTypeof(UnaryOperation* expr); - void VisitAdd(UnaryOperation* expr); void VisitSub(UnaryOperation* expr); void VisitBitNot(UnaryOperation* expr); void VisitNot(UnaryOperation* expr); diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc index 05dceb7e28..84fe688f72 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.cc +++ b/deps/v8/src/ia32/code-stubs-ia32.cc @@ -30,7 +30,6 @@ #if defined(V8_TARGET_ARCH_IA32) #include "bootstrapper.h" -#include "builtins-decls.h" #include "code-stubs.h" #include "isolate.h" #include "jsregexp.h" diff --git a/deps/v8/src/ia32/code-stubs-ia32.h b/deps/v8/src/ia32/code-stubs-ia32.h index c2ae5f0fae..07563cd02a 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.h +++ b/deps/v8/src/ia32/code-stubs-ia32.h @@ -144,7 +144,7 @@ class UnaryOpStub: public PlatformCodeStub { void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm); - virtual int GetCodeKind() { return Code::UNARY_OP_IC; } + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } virtual InlineCacheState GetICState() { return UnaryOpIC::ToState(operand_type_); diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index 19989b1c62..a35f12d8cc 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -3967,18 +3967,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::ADD: { - Comment cmt(masm_, "[ UnaryOperation (ADD)"); - VisitForAccumulatorValue(expr->expression()); - Label no_conversion; - __ JumpIfSmi(result_register(), &no_conversion); - ToNumberStub convert_stub; - __ CallStub(&convert_stub); - __ bind(&no_conversion); - context()->Plug(result_register()); - break; - } - case Token::SUB: EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); break; diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc index 1dcad043e6..665c85e827 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc @@ -467,7 +467,7 @@ bool LCodeGen::GenerateDeferredCode() { LDeferredCode* code = deferred_[i]; __ bind(code->entry()); if (NeedsDeferredFrame()) { - Comment(";;; Deferred build frame", + Comment(";;; Deferred build frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(!frame_is_built_); @@ -484,7 +484,7 @@ bool LCodeGen::GenerateDeferredCode() { code->instr()->Mnemonic()); code->Generate(); if (NeedsDeferredFrame()) { - Comment(";;; Deferred destroy frame", + Comment(";;; Deferred destroy frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(frame_is_built_); @@ -1126,11 +1126,9 @@ void LCodeGen::RecordPosition(int position) { void LCodeGen::DoLabel(LLabel* label) { - if (label->is_loop_header()) { - Comment(";;; B%d - LOOP entry", label->block_id()); - } else { - Comment(";;; B%d", label->block_id()); - } + Comment(";;; -------------------- B%d%s --------------------", + label->block_id(), + label->is_loop_header() ? " (loop header)" : ""); __ bind(label->label()); current_block_ = label->block_id(); DoGap(label); @@ -2287,11 +2285,15 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register left = ToRegister(instr->left()); - Operand right = ToOperand(instr->right()); int false_block = chunk_->LookupDestination(instr->false_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id()); - __ cmp(left, Operand(right)); + if (instr->right()->IsConstantOperand()) { + __ cmp(left, ToHandle(LConstantOperand::cast(instr->right()))); + } else { + Operand right = ToOperand(instr->right()); + __ cmp(left, Operand(right)); + } EmitBranch(true_block, false_block, equal); } diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h index 362f091d2b..b268456b7d 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.h +++ b/deps/v8/src/ia32/lithium-codegen-ia32.h @@ -32,9 +32,10 @@ #include "checks.h" #include "deoptimizer.h" +#include "ia32/lithium-gap-resolver-ia32.h" #include "safepoint-table.h" #include "scopes.h" -#include "ia32/lithium-gap-resolver-ia32.h" +#include "v8utils.h" namespace v8 { namespace internal { @@ -201,7 +202,7 @@ class LCodeGen BASE_EMBEDDED { int GetStackSlotCount() const { return chunk()->spill_slot_count(); } void Abort(const char* reason); - void Comment(const char* format, ...); + void FPRINTF_CHECKING Comment(const char* format, ...); void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc index a7bb2d95fb..c4a8be1bcc 100644 --- a/deps/v8/src/ia32/lithium-ia32.cc +++ b/deps/v8/src/ia32/lithium-ia32.cc @@ -884,11 +884,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { HEnvironment* last_environment = pred->last_environment(); for (int i = 0; i < block->phis()->length(); ++i) { HPhi* phi = block->phis()->at(i); - last_environment->SetValueAt(phi->merged_index(), phi); + if (phi->merged_index() < last_environment->length()) { + last_environment->SetValueAt(phi->merged_index(), phi); + } } for (int i = 0; i < block->deleted_phis()->length(); ++i) { - last_environment->SetValueAt(block->deleted_phis()->at(i), - graph_->GetConstantUndefined()); + if (block->deleted_phis()->at(i) < last_environment->length()) { + last_environment->SetValueAt(block->deleted_phis()->at(i), + graph_->GetConstantUndefined()); + } } block->UpdateEnvironment(last_environment); // Pick up the outgoing argument count of one of the predecessors. @@ -1693,7 +1697,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch( LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( HCompareObjectEqAndBranch* instr) { LOperand* left = UseRegisterAtStart(instr->left()); - LOperand* right = UseAtStart(instr->right()); + LOperand* right = UseOrConstantAtStart(instr->right()); return new(zone()) LCmpObjectEqAndBranch(left, right); } diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index 3c33e4ff32..78fb29753c 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -1384,7 +1384,7 @@ MaybeObject* KeyedLoadIC::Load(State state, } - return Runtime::GetObjectProperty(isolate(), object, key); + return Runtime::GetObjectPropertyOrFail(isolate(), object, key); } @@ -1972,7 +1972,7 @@ MaybeObject* KeyedStoreIC::Store(State state, TRACE_IC("KeyedStoreIC", key, state, target()); } - return Runtime::SetObjectProperty( + return Runtime::SetObjectPropertyOrFail( isolate(), object , key, value, NONE, strict_mode); } diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc index 09c0f4405f..b4a57f520b 100644 --- a/deps/v8/src/lithium.cc +++ b/deps/v8/src/lithium.cc @@ -442,7 +442,7 @@ LChunk* LChunk::NewChunk(HGraph* graph) { } -Handle<Code> LChunk::Codegen(Code::Kind kind) { +Handle<Code> LChunk::Codegen() { MacroAssembler assembler(info()->isolate(), NULL, 0); LOG_CODE_EVENT(info()->isolate(), CodeStartLinePosInfoRecordEvent( @@ -456,11 +456,11 @@ Handle<Code> LChunk::Codegen(Code::Kind kind) { PrintF("Crankshaft Compiler - "); } CodeGenerator::MakeCodePrologue(info()); - Code::Flags flags = Code::ComputeFlags(kind); + Code::Flags flags = info()->flags(); Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); generator.FinishCode(code); - + code->set_is_crankshafted(true); if (!code.is_null()) { void* jit_handler_data = assembler.positions_recorder()->DetachJITHandlerData(); diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h index 9d5b0b9eec..24182747e3 100644 --- a/deps/v8/src/lithium.h +++ b/deps/v8/src/lithium.h @@ -685,7 +685,7 @@ class LChunk: public ZoneObject { Zone* zone() const { return info_->zone(); } - Handle<Code> Codegen(Code::Kind kind); + Handle<Code> Codegen(); void set_allocated_double_registers(BitVector* allocated_registers); BitVector* allocated_double_registers() { diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc index 1538894643..55f5637d55 100644 --- a/deps/v8/src/log.cc +++ b/deps/v8/src/log.cc @@ -1590,7 +1590,6 @@ void Logger::LogCodeObject(Object* object) { case Code::BINARY_OP_IC: // fall through case Code::COMPARE_IC: // fall through case Code::TO_BOOLEAN_IC: // fall through - case Code::COMPILED_STUB: // fall through case Code::STUB: description = CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true); diff --git a/deps/v8/src/macros.py b/deps/v8/src/macros.py index 92ed437b0f..0c52f3822e 100644 --- a/deps/v8/src/macros.py +++ b/deps/v8/src/macros.py @@ -117,6 +117,7 @@ macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script'); macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments'); macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global'); macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer'); +macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator'); macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg)); macro FLOOR(arg) = $floor(arg); diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc index cbe2048076..27fd73231a 100644 --- a/deps/v8/src/mips/code-stubs-mips.cc +++ b/deps/v8/src/mips/code-stubs-mips.cc @@ -30,7 +30,6 @@ #if defined(V8_TARGET_ARCH_MIPS) #include "bootstrapper.h" -#include "builtins-decls.h" #include "code-stubs.h" #include "codegen.h" #include "regexp-macro-assembler.h" diff --git a/deps/v8/src/mips/code-stubs-mips.h b/deps/v8/src/mips/code-stubs-mips.h index 0ebfe59956..2370d4537d 100644 --- a/deps/v8/src/mips/code-stubs-mips.h +++ b/deps/v8/src/mips/code-stubs-mips.h @@ -131,7 +131,7 @@ class UnaryOpStub: public PlatformCodeStub { void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm); - virtual int GetCodeKind() { return Code::UNARY_OP_IC; } + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } virtual InlineCacheState GetICState() { return UnaryOpIC::ToState(operand_type_); diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index 8e2d5abbed..bc0d85543b 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -3995,19 +3995,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::ADD: { - Comment cmt(masm_, "[ UnaryOperation (ADD)"); - VisitForAccumulatorValue(expr->expression()); - Label no_conversion; - __ JumpIfSmi(result_register(), &no_conversion); - __ mov(a0, result_register()); - ToNumberStub convert_stub; - __ CallStub(&convert_stub); - __ bind(&no_conversion); - context()->Plug(result_register()); - break; - } - case Token::SUB: EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); break; diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc index 59cfcd9000..77949313e1 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.cc +++ b/deps/v8/src/mips/lithium-codegen-mips.cc @@ -301,7 +301,7 @@ bool LCodeGen::GenerateDeferredCode() { LDeferredCode* code = deferred_[i]; __ bind(code->entry()); if (NeedsDeferredFrame()) { - Comment(";;; Deferred build frame", + Comment(";;; Deferred build frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(!frame_is_built_); @@ -317,7 +317,7 @@ bool LCodeGen::GenerateDeferredCode() { code->instr()->Mnemonic()); code->Generate(); if (NeedsDeferredFrame()) { - Comment(";;; Deferred destroy frame", + Comment(";;; Deferred destroy frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(frame_is_built_); @@ -1024,11 +1024,9 @@ void LCodeGen::RecordPosition(int position) { void LCodeGen::DoLabel(LLabel* label) { - if (label->is_loop_header()) { - Comment(";;; B%d - LOOP entry", label->block_id()); - } else { - Comment(";;; B%d", label->block_id()); - } + Comment(";;; -------------------- B%d%s --------------------", + label->block_id(), + label->is_loop_header() ? " (loop header)" : ""); __ bind(label->label()); current_block_ = label->block_id(); DoGap(label); diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h index a1bc4ba4dc..01d0ffcbee 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.h +++ b/deps/v8/src/mips/lithium-codegen-mips.h @@ -28,11 +28,12 @@ #ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_ #define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_ -#include "mips/lithium-mips.h" -#include "mips/lithium-gap-resolver-mips.h" #include "deoptimizer.h" +#include "mips/lithium-gap-resolver-mips.h" +#include "mips/lithium-mips.h" #include "safepoint-table.h" #include "scopes.h" +#include "v8utils.h" namespace v8 { namespace internal { @@ -207,7 +208,7 @@ class LCodeGen BASE_EMBEDDED { int GetStackSlotCount() const { return chunk()->spill_slot_count(); } void Abort(const char* reason); - void Comment(const char* format, ...); + void FPRINTF_CHECKING Comment(const char* format, ...); void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index efc1764ddf..f3a029ee34 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -3645,9 +3645,21 @@ int Code::arguments_count() { } +inline bool Code::is_crankshafted() { + return IsCrankshaftedField::decode( + READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)); +} + + +inline void Code::set_is_crankshafted(bool value) { + int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); + int updated = IsCrankshaftedField::update(previous, value); + WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated); +} + + int Code::major_key() { ASSERT(kind() == STUB || - kind() == COMPILED_STUB || kind() == UNARY_OP_IC || kind() == BINARY_OP_IC || kind() == COMPARE_IC || @@ -3661,7 +3673,6 @@ int Code::major_key() { void Code::set_major_key(int major) { ASSERT(kind() == STUB || - kind() == COMPILED_STUB || kind() == UNARY_OP_IC || kind() == BINARY_OP_IC || kind() == COMPARE_IC || @@ -3774,7 +3785,7 @@ void Code::set_profiler_ticks(int ticks) { unsigned Code::stack_slots() { - ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); + ASSERT(is_crankshafted()); return StackSlotsField::decode( READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); } @@ -3782,7 +3793,7 @@ unsigned Code::stack_slots() { void Code::set_stack_slots(unsigned slots) { CHECK(slots <= (1 << kStackSlotsBitCount)); - ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); + ASSERT(is_crankshafted()); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); int updated = StackSlotsField::update(previous, slots); WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); @@ -3790,7 +3801,7 @@ void Code::set_stack_slots(unsigned slots) { unsigned Code::safepoint_table_offset() { - ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); + ASSERT(is_crankshafted()); return SafepointTableOffsetField::decode( READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)); } @@ -3798,7 +3809,7 @@ unsigned Code::safepoint_table_offset() { void Code::set_safepoint_table_offset(unsigned offset) { CHECK(offset <= (1 << kSafepointTableOffsetBitCount)); - ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB); + ASSERT(is_crankshafted()); ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize))); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); int updated = SafepointTableOffsetField::update(previous, offset); diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc index aa71a961be..f21481ab0b 100644 --- a/deps/v8/src/objects-printer.cc +++ b/deps/v8/src/objects-printer.cc @@ -187,8 +187,10 @@ void HeapObject::HeapObjectPrint(FILE* out) { break; case JS_ARRAY_BUFFER_TYPE: JSArrayBuffer::cast(this)->JSArrayBufferPrint(out); + break; case JS_TYPED_ARRAY_TYPE: JSTypedArray::cast(this)->JSTypedArrayPrint(out); + break; #define MAKE_STRUCT_CASE(NAME, Name, name) \ case NAME##_TYPE: \ Name::cast(this)->Name##Print(out); \ diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index 33be173a56..2092859cd5 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -9313,7 +9313,6 @@ const char* Code::Kind2String(Kind kind) { switch (kind) { case FUNCTION: return "FUNCTION"; case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; - case COMPILED_STUB: return "COMPILED_STUB"; case STUB: return "STUB"; case BUILTIN: return "BUILTIN"; case LOAD_IC: return "LOAD_IC"; @@ -9613,7 +9612,7 @@ void Code::Disassemble(const char* name, FILE* out) { } PrintF("\n"); - if (kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB) { + if (is_crankshafted()) { SafepointTable table(this); PrintF(out, "Safepoints (size = %u)\n", table.size()); for (unsigned i = 0; i < table.length(); i++) { diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 898b176215..3ca89f08ea 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -4327,7 +4327,6 @@ class Code: public HeapObject { V(FUNCTION) \ V(OPTIMIZED_FUNCTION) \ V(STUB) \ - V(COMPILED_STUB) \ V(BUILTIN) \ V(LOAD_IC) \ V(KEYED_LOAD_IC) \ @@ -4470,6 +4469,11 @@ class Code: public HeapObject { inline int major_key(); inline void set_major_key(int value); + // For kind STUB or ICs, tells whether or not a code object was generated by + // the optimizing compiler (but it may not be an optimized function). + bool is_crankshafted(); + inline void set_is_crankshafted(bool value); + // For stubs, tells whether they should always exist, so that they can be // called from other stubs. inline bool is_pregenerated(); @@ -4785,15 +4789,22 @@ class Code: public HeapObject { kMarkedForDeoptimizationFirstBit, kMarkedForDeoptimizationBitCount> {}; // NOLINT + // KindSpecificFlags2 layout (ALL) + static const int kIsCrankshaftedBit = 0; + class IsCrankshaftedField: public BitField<bool, + kIsCrankshaftedBit, 1> {}; // NOLINT + // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION) - static const int kStubMajorKeyFirstBit = 0; + static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1; static const int kSafepointTableOffsetFirstBit = kStubMajorKeyFirstBit + kStubMajorKeyBits; - static const int kSafepointTableOffsetBitCount = 26; + static const int kSafepointTableOffsetBitCount = 25; STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32); STATIC_ASSERT(kSafepointTableOffsetFirstBit + kSafepointTableOffsetBitCount <= 32); + STATIC_ASSERT(1 + kStubMajorKeyBits + + kSafepointTableOffsetBitCount <= 32); class SafepointTableOffsetField: public BitField<int, kSafepointTableOffsetFirstBit, @@ -4802,8 +4813,10 @@ class Code: public HeapObject { kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT // KindSpecificFlags2 layout (FUNCTION) - class BackEdgeTableOffsetField: public BitField<int, 0, 31> {}; - class BackEdgesPatchedForOSRField: public BitField<bool, 31, 1> {}; + class BackEdgeTableOffsetField: public BitField<int, + kIsCrankshaftedBit + 1, 29> {}; // NOLINT + class BackEdgesPatchedForOSRField: public BitField<bool, + kIsCrankshaftedBit + 1 + 29, 1> {}; // NOLINT // Signed field cannot be encoded using the BitField class. static const int kArgumentsCountShift = 17; diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc index b4ab623829..b63911bc97 100644 --- a/deps/v8/src/parser.cc +++ b/deps/v8/src/parser.cc @@ -1872,9 +1872,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { const int literals = fun->NumberOfLiterals(); Handle<Code> code = Handle<Code>(fun->shared()->code()); Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); + bool is_generator = false; Handle<SharedFunctionInfo> shared = - isolate()->factory()->NewSharedFunctionInfo(name, literals, code, - Handle<ScopeInfo>(fun->shared()->scope_info())); + isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator, + code, Handle<ScopeInfo>(fun->shared()->scope_info())); shared->set_construct_stub(*construct_stub); // Copy the function data to the shared function info. @@ -3286,6 +3287,16 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { } } + // Desugar '+foo' into 'foo*1', this enables the collection of type feedback + // without any special stub and the multiplication is removed later in + // Crankshaft's canonicalization pass. + if (op == Token::ADD) { + return factory()->NewBinaryOperation(Token::MUL, + expression, + factory()->NewNumberLiteral(1), + position); + } + return factory()->NewUnaryOperation(op, expression, position); } else if (Token::IsCountOp(op)) { diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc index 735f078994..eadcf55f28 100644 --- a/deps/v8/src/platform-freebsd.cc +++ b/deps/v8/src/platform-freebsd.cc @@ -194,9 +194,7 @@ void OS::Abort() { void OS::DebugBreak() { #if (defined(__arm__) || defined(__thumb__)) -# if defined(CAN_USE_ARMV5_INSTRUCTIONS) asm("bkpt 0"); -# endif #else asm("int $3"); #endif diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc index 38f7c67834..a6402d73dd 100644 --- a/deps/v8/src/platform-linux.cc +++ b/deps/v8/src/platform-linux.cc @@ -419,9 +419,7 @@ void OS::DebugBreak() { // TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x, // which is the architecture of generated code). #if (defined(__arm__) || defined(__thumb__)) -# if defined(CAN_USE_ARMV5_INSTRUCTIONS) asm("bkpt 0"); -# endif #elif defined(__mips__) asm("break"); #elif defined(__native_client__) diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc index 2cf898dd60..48898ed9aa 100644 --- a/deps/v8/src/platform-posix.cc +++ b/deps/v8/src/platform-posix.cc @@ -115,26 +115,11 @@ void* OS::GetRandomMmapAddr() { raw_addr &= V8_UINT64_C(0x3ffffffff000); #else uint32_t raw_addr = V8::RandomPrivate(isolate); - - raw_addr &= 0x3ffff000; - -# ifdef __sun - // For our Solaris/illumos mmap hint, we pick a random address in the bottom - // half of the top half of the address space (that is, the third quarter). - // Because we do not MAP_FIXED, this will be treated only as a hint -- the - // system will not fail to mmap() because something else happens to already - // be mapped at our random address. We deliberately set the hint high enough - // to get well above the system's break (that is, the heap); Solaris and - // illumos will try the hint and if that fails allocate as if there were - // no hint at all. The high hint prevents the break from getting hemmed in - // at low values, ceding half of the address space to the system heap. - raw_addr += 0x80000000; -# else // The range 0x20000000 - 0x60000000 is relatively unpopulated across a // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos // 10.6 and 10.7. + raw_addr &= 0x3ffff000; raw_addr += 0x20000000; -# endif #endif return reinterpret_cast<void*>(raw_addr); } diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc index 752d79c982..95e86b119c 100644 --- a/deps/v8/src/runtime-profiler.cc +++ b/deps/v8/src/runtime-profiler.cc @@ -30,6 +30,7 @@ #include "runtime-profiler.h" #include "assembler.h" +#include "bootstrapper.h" #include "code-stubs.h" #include "compilation-cache.h" #include "deoptimizer.h" @@ -134,7 +135,7 @@ void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) { PrintF("]\n"); } - if (FLAG_parallel_recompilation) { + if (FLAG_parallel_recompilation && !isolate_->bootstrapper()->IsActive()) { ASSERT(!function->IsMarkedForInstallingRecompiledCode()); ASSERT(!function->IsInRecompileQueue()); function->MarkForParallelRecompilation(); diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index 7e7d6d5d58..c0213d2ea4 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -706,9 +706,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { holder->set_byte_length(byte_length); v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate); - v8::Handle<Object> external_holder(*holder); - Persistent<Object> weak_handle = Persistent<Object>::New( - external_isolate, external_holder); + v8::Persistent<v8::Value> weak_handle = v8::Persistent<v8::Value>::New( + external_isolate, v8::Utils::ToLocal(Handle<Object>::cast(holder))); weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback); weak_handle.MarkIndependent(external_isolate); isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); @@ -734,8 +733,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) { size_t start = static_cast<size_t>(first); size_t target_length = NumberToSize(isolate, target->byte_length()); - if (target_length == 0) - return isolate->heap()->undefined_value(); + if (target_length == 0) return isolate->heap()->undefined_value(); ASSERT(NumberToSize(isolate, source->byte_length()) - target_length >= start); uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store()); @@ -2417,11 +2415,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, Object* char_code) { - uint32_t code; - if (char_code->ToArrayIndex(&code)) { - if (code <= 0xffff) { - return isolate->heap()->LookupSingleCharacterStringFromCode(code); - } + if (char_code->IsNumber()) { + return isolate->heap()->LookupSingleCharacterStringFromCode( + NumberToUint32(char_code) & 0xffff); } return isolate->heap()->empty_string(); } @@ -4096,6 +4092,13 @@ MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, return isolate->heap()->ToBoolean(object->HasProperty(*name)); } +MaybeObject* Runtime::GetObjectPropertyOrFail( + Isolate* isolate, + Handle<Object> object, + Handle<Object> key) { + CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, + GetObjectProperty(isolate, object, key)); +} MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, Handle<Object> object, @@ -4380,6 +4383,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { } +MaybeObject* Runtime::SetObjectPropertyOrFail( + Isolate* isolate, + Handle<Object> object, + Handle<Object> key, + Handle<Object> value, + PropertyAttributes attr, + StrictModeFlag strict_mode) { + CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, + SetObjectProperty(isolate, object, key, value, attr, strict_mode)); +} + + MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, Handle<Object> object, Handle<Object> key, @@ -7636,7 +7651,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyStubFailure) { ASSERT(args.length() == 0); Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); ASSERT(isolate->heap()->IsAllocationAllowed()); - ASSERT(deoptimizer->compiled_code_kind() == Code::COMPILED_STUB); delete deoptimizer; return isolate->heap()->undefined_value(); } @@ -7651,7 +7665,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); ASSERT(isolate->heap()->IsAllocationAllowed()); - ASSERT(deoptimizer->compiled_code_kind() != Code::COMPILED_STUB); + ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); // Make sure to materialize objects before causing any allocation. JavaScriptFrameIterator it(isolate); diff --git a/deps/v8/src/runtime.h b/deps/v8/src/runtime.h index cbf70e95ce..14133511ea 100644 --- a/deps/v8/src/runtime.h +++ b/deps/v8/src/runtime.h @@ -702,6 +702,14 @@ class Runtime : public AllStatic { PropertyAttributes attr, StrictModeFlag strict_mode); + MUST_USE_RESULT static MaybeObject* SetObjectPropertyOrFail( + Isolate* isolate, + Handle<Object> object, + Handle<Object> key, + Handle<Object> value, + PropertyAttributes attr, + StrictModeFlag strict_mode); + MUST_USE_RESULT static MaybeObject* ForceSetObjectProperty( Isolate* isolate, Handle<JSObject> object, @@ -725,6 +733,11 @@ class Runtime : public AllStatic { Handle<Object> object, Handle<Object> key); + MUST_USE_RESULT static MaybeObject* GetObjectPropertyOrFail( + Isolate* isolate, + Handle<Object> object, + Handle<Object> key); + // Helper functions used stubs. static void PerformGC(Object* result); diff --git a/deps/v8/src/safepoint-table.cc b/deps/v8/src/safepoint-table.cc index 9e423045ae..b56556572e 100644 --- a/deps/v8/src/safepoint-table.cc +++ b/deps/v8/src/safepoint-table.cc @@ -59,8 +59,7 @@ bool SafepointEntry::HasRegisterAt(int reg_index) const { SafepointTable::SafepointTable(Code* code) { - ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION || - code->kind() == Code::COMPILED_STUB); + ASSERT(code->is_crankshafted()); code_ = code; Address header = code->instruction_start() + code->safepoint_table_offset(); length_ = Memory::uint32_at(header + kLengthOffset); diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc index e413bf1fff..7202e1bbc0 100644 --- a/deps/v8/src/spaces.cc +++ b/deps/v8/src/spaces.cc @@ -1807,7 +1807,6 @@ static void ReportCodeKindStatistics() { CASE(FUNCTION); CASE(OPTIMIZED_FUNCTION); CASE(STUB); - CASE(COMPILED_STUB); CASE(BUILTIN); CASE(LOAD_IC); CASE(KEYED_LOAD_IC); diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 933e2540a4..8a1b8b7517 100644 --- a/deps/v8/src/version.cc +++ b/deps/v8/src/version.cc @@ -34,7 +34,7 @@ // cannot be changed without changing the SCons build script. #define MAJOR_VERSION 3 #define MINOR_VERSION 18 -#define BUILD_NUMBER 0 +#define BUILD_NUMBER 1 #define PATCH_LEVEL 0 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc index 787c7fb518..3958cf0324 100644 --- a/deps/v8/src/x64/code-stubs-x64.cc +++ b/deps/v8/src/x64/code-stubs-x64.cc @@ -30,7 +30,6 @@ #if defined(V8_TARGET_ARCH_X64) #include "bootstrapper.h" -#include "builtins-decls.h" #include "code-stubs.h" #include "regexp-macro-assembler.h" #include "stub-cache.h" @@ -4273,10 +4272,6 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { Label invoke, handler_entry, exit; Label not_outermost_js, not_outermost_js_2; -#ifdef _WIN64 - const int kCalleeSaveXMMRegisters = 10; - const int kFullXMMRegisterSize = 16; -#endif { // NOLINT. Scope block confuses linter. MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); // Set up frame. @@ -4306,17 +4301,17 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { #ifdef _WIN64 // On Win64 XMM6-XMM15 are callee-save - __ subq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize)); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 0), xmm6); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 1), xmm7); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 2), xmm8); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 3), xmm9); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 4), xmm10); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 5), xmm11); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 6), xmm12); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 7), xmm13); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 8), xmm14); - __ movdqu(Operand(rsp, kFullXMMRegisterSize * 9), xmm15); + __ subq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize)); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0), xmm6); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1), xmm7); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2), xmm8); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3), xmm9); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4), xmm10); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5), xmm11); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6), xmm12); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7), xmm13); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8), xmm14); + __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9), xmm15); #endif // Set up the roots and smi constant registers. @@ -4409,17 +4404,17 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Restore callee-saved registers (X64 conventions). #ifdef _WIN64 // On Win64 XMM6-XMM15 are callee-save - __ movdqu(xmm6, Operand(rsp, kFullXMMRegisterSize * 0)); - __ movdqu(xmm7, Operand(rsp, kFullXMMRegisterSize * 1)); - __ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 2)); - __ movdqu(xmm8, Operand(rsp, kFullXMMRegisterSize * 3)); - __ movdqu(xmm10, Operand(rsp, kFullXMMRegisterSize * 4)); - __ movdqu(xmm11, Operand(rsp, kFullXMMRegisterSize * 5)); - __ movdqu(xmm12, Operand(rsp, kFullXMMRegisterSize * 6)); - __ movdqu(xmm13, Operand(rsp, kFullXMMRegisterSize * 7)); - __ movdqu(xmm14, Operand(rsp, kFullXMMRegisterSize * 8)); - __ movdqu(xmm15, Operand(rsp, kFullXMMRegisterSize * 9)); - __ addq(rsp, Immediate(kCalleeSaveXMMRegisters * kFullXMMRegisterSize)); + __ movdqu(xmm6, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0)); + __ movdqu(xmm7, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1)); + __ movdqu(xmm8, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 2)); + __ movdqu(xmm9, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 3)); + __ movdqu(xmm10, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 4)); + __ movdqu(xmm11, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 5)); + __ movdqu(xmm12, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 6)); + __ movdqu(xmm13, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 7)); + __ movdqu(xmm14, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 8)); + __ movdqu(xmm15, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 9)); + __ addq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize)); #endif __ pop(rbx); diff --git a/deps/v8/src/x64/code-stubs-x64.h b/deps/v8/src/x64/code-stubs-x64.h index 5dd4064a57..72a3a95d1b 100644 --- a/deps/v8/src/x64/code-stubs-x64.h +++ b/deps/v8/src/x64/code-stubs-x64.h @@ -138,7 +138,7 @@ class UnaryOpStub: public PlatformCodeStub { void GenerateGenericStubBitNot(MacroAssembler* masm); void GenerateGenericCodeFallback(MacroAssembler* masm); - virtual int GetCodeKind() { return Code::UNARY_OP_IC; } + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; } virtual InlineCacheState GetICState() { return UnaryOpIC::ToState(operand_type_); diff --git a/deps/v8/src/x64/frames-x64.h b/deps/v8/src/x64/frames-x64.h index 14cc5b8f21..a24ab53107 100644 --- a/deps/v8/src/x64/frames-x64.h +++ b/deps/v8/src/x64/frames-x64.h @@ -51,7 +51,12 @@ const int kNumSafepointRegisters = 16; class EntryFrameConstants : public AllStatic { public: #ifdef _WIN64 - static const int kCallerFPOffset = -10 * kPointerSize; + static const int kCalleeSaveXMMRegisters = 10; + static const int kXMMRegisterSize = 16; + static const int kXMMRegistersBlockSize = + kXMMRegisterSize * kCalleeSaveXMMRegisters; + static const int kCallerFPOffset = + -10 * kPointerSize - kXMMRegistersBlockSize; #else static const int kCallerFPOffset = -8 * kPointerSize; #endif diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc index 564c3def86..8ca173b30f 100644 --- a/deps/v8/src/x64/full-codegen-x64.cc +++ b/deps/v8/src/x64/full-codegen-x64.cc @@ -3968,18 +3968,6 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { break; } - case Token::ADD: { - Comment cmt(masm_, "[ UnaryOperation (ADD)"); - VisitForAccumulatorValue(expr->expression()); - Label no_conversion; - __ JumpIfSmi(result_register(), &no_conversion); - ToNumberStub convert_stub; - __ CallStub(&convert_stub); - __ bind(&no_conversion); - context()->Plug(result_register()); - break; - } - case Token::SUB: EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); break; diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc index 6fc56ed1eb..3e8fd5c72f 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.cc +++ b/deps/v8/src/x64/lithium-codegen-x64.cc @@ -370,7 +370,7 @@ bool LCodeGen::GenerateDeferredCode() { LDeferredCode* code = deferred_[i]; __ bind(code->entry()); if (NeedsDeferredFrame()) { - Comment(";;; Deferred build frame", + Comment(";;; Deferred build frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(!frame_is_built_); @@ -387,7 +387,7 @@ bool LCodeGen::GenerateDeferredCode() { code->instr()->Mnemonic()); code->Generate(); if (NeedsDeferredFrame()) { - Comment(";;; Deferred destroy frame", + Comment(";;; Deferred destroy frame @%d: %s.", code->instruction_index(), code->instr()->Mnemonic()); ASSERT(frame_is_built_); @@ -926,11 +926,9 @@ void LCodeGen::RecordPosition(int position) { void LCodeGen::DoLabel(LLabel* label) { - if (label->is_loop_header()) { - Comment(";;; B%d - LOOP entry", label->block_id()); - } else { - Comment(";;; B%d", label->block_id()); - } + Comment(";;; -------------------- B%d%s --------------------", + label->block_id(), + label->is_loop_header() ? " (loop header)" : ""); __ bind(label->label()); current_block_ = label->block_id(); DoGap(label); @@ -2055,11 +2053,14 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register left = ToRegister(instr->left()); - Register right = ToRegister(instr->right()); int false_block = chunk_->LookupDestination(instr->false_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id()); - __ cmpq(left, right); + if (instr->right()->IsConstantOperand()) { + __ Cmp(left, ToHandle(LConstantOperand::cast(instr->right()))); + } else { + __ cmpq(left, ToRegister(instr->right())); + } EmitBranch(true_block, false_block, equal); } diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h index e857606830..adcc3e5b26 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.h +++ b/deps/v8/src/x64/lithium-codegen-x64.h @@ -34,6 +34,7 @@ #include "deoptimizer.h" #include "safepoint-table.h" #include "scopes.h" +#include "v8utils.h" #include "x64/lithium-gap-resolver-x64.h" namespace v8 { @@ -172,7 +173,7 @@ class LCodeGen BASE_EMBEDDED { int GetStackSlotCount() const { return chunk()->spill_slot_count(); } void Abort(const char* reason); - void Comment(const char* format, ...); + void FPRINTF_CHECKING Comment(const char* format, ...); void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc index ba29ed969d..1d42455ce3 100644 --- a/deps/v8/src/x64/lithium-x64.cc +++ b/deps/v8/src/x64/lithium-x64.cc @@ -831,11 +831,15 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { HEnvironment* last_environment = pred->last_environment(); for (int i = 0; i < block->phis()->length(); ++i) { HPhi* phi = block->phis()->at(i); - last_environment->SetValueAt(phi->merged_index(), phi); + if (phi->merged_index() < last_environment->length()) { + last_environment->SetValueAt(phi->merged_index(), phi); + } } for (int i = 0; i < block->deleted_phis()->length(); ++i) { - last_environment->SetValueAt(block->deleted_phis()->at(i), - graph_->GetConstantUndefined()); + if (block->deleted_phis()->at(i) < last_environment->length()) { + last_environment->SetValueAt(block->deleted_phis()->at(i), + graph_->GetConstantUndefined()); + } } block->UpdateEnvironment(last_environment); // Pick up the outgoing argument count of one of the predecessors. @@ -1610,7 +1614,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch( LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( HCompareObjectEqAndBranch* instr) { LOperand* left = UseRegisterAtStart(instr->left()); - LOperand* right = UseRegisterAtStart(instr->right()); + LOperand* right = UseRegisterOrConstantAtStart(instr->right()); return new(zone()) LCmpObjectEqAndBranch(left, right); } diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py deleted file mode 100644 index 5bbad7ac1b..0000000000 --- a/deps/v8/test/benchmarks/testcfg.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2011 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import test -import os -from os.path import join, split - -def GetSuite(name, root): - # Not implemented. - return None - - -def IsNumber(string): - try: - float(string) - return True - except ValueError: - return False - - -class BenchmarkTestCase(test.TestCase): - - def __init__(self, path, context, mode): - super(BenchmarkTestCase, self).__init__(context, split(path), mode) - self.root = path - - def GetLabel(self): - return '%s benchmark %s' % (self.mode, self.GetName()) - - def IsFailureOutput(self, output): - if output.exit_code != 0: - return True - lines = output.stdout.splitlines() - for line in lines: - colon_index = line.find(':') - if colon_index >= 0: - if not IsNumber(line[colon_index+1:].strip()): - return True - return False - - def GetCommand(self): - result = self.context.GetVmCommand(self, self.mode) - result.append(join(self.root, 'run.js')) - return result - - def GetName(self): - return 'V8' - - def BeforeRun(self): - os.chdir(self.root) - - def AfterRun(self, result): - os.chdir(self.context.buildspace) - - def GetSource(self): - return open(join(self.root, 'run.js')).read() - - def GetCustomFlags(self, mode): - return [] - - -class BenchmarkTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(BenchmarkTestConfiguration, self).__init__(context, root) - - def ListTests(self, current_path, path, mode, variant_flags): - path = self.context.workspace - path = join(path, 'benchmarks') - test = BenchmarkTestCase(path, self.context, mode) - return [test] - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - pass - -def GetConfiguration(context, root): - return BenchmarkTestConfiguration(context, root) diff --git a/deps/v8/test/cctest/SConscript b/deps/v8/test/cctest/SConscript deleted file mode 100644 index ce42b0d72b..0000000000 --- a/deps/v8/test/cctest/SConscript +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import sys -from os.path import join, dirname, abspath -root_dir = dirname(File('SConstruct').rfile().abspath) -sys.path.append(join(root_dir, 'tools')) -import js2c -Import('context object_files tools') - - -# Needed for test-log. Paths are relative to the cctest dir. -JS_FILES_FOR_TESTS = [ - '../../../tools/splaytree.js', - '../../../tools/codemap.js', - '../../../tools/csvparser.js', - '../../../tools/consarray.js', - '../../../tools/profile.js', - '../../../tools/profile_view.js', - '../../../tools/logreader.js', - 'log-eq-of-logging-and-traversal.js', -] - - -SOURCES = { - 'all': [ - 'gay-fixed.cc', - 'gay-precision.cc', - 'gay-shortest.cc', - 'test-accessors.cc', - 'test-alloc.cc', - 'test-api.cc', - 'test-ast.cc', - 'test-bignum-dtoa.cc', - 'test-bignum.cc', - 'test-circular-queue.cc', - 'test-compiler.cc', - 'test-conversions.cc', - 'test-cpu-profiler.cc', - 'test-dataflow.cc', - 'test-date.cc', - 'test-debug.cc', - 'test-declarative-accessors.cc', - 'test-decls.cc', - 'test-deoptimization.cc', - 'test-dictionary.cc', - 'test-diy-fp.cc', - 'test-double.cc', - 'test-dtoa.cc', - 'test-fast-dtoa.cc', - 'test-fixed-dtoa.cc', - 'test-flags.cc', - 'test-func-name-inference.cc', - 'test-hashing.cc', - 'test-hashmap.cc', - 'test-heap-profiler.cc', - 'test-heap.cc', - 'test-list.cc', - 'test-liveedit.cc', - 'test-lock.cc', - 'test-lockers.cc', - 'test-log.cc', - 'test-mark-compact.cc', - 'test-parsing.cc', - 'test-platform-tls.cc', - 'test-profile-generator.cc', - 'test-random.cc', - 'test-regexp.cc', - 'test-reloc-info.cc', - 'test-serialize.cc', - 'test-sockets.cc', - 'test-spaces.cc', - 'test-strings.cc', - 'test-symbols.cc', - 'test-strtod.cc', - 'test-thread-termination.cc', - 'test-threads.cc', - 'test-unbound-queue.cc', - 'test-utils.cc', - 'test-version.cc', - 'test-weakmaps.cc' - ], - 'arch:arm': [ - 'test-assembler-arm.cc', - 'test-disasm-arm.cc' - ], - 'arch:ia32': [ - 'test-assembler-ia32.cc', - 'test-disasm-ia32.cc', - 'test-log-stack-tracer.cc' - ], - 'arch:x64': ['test-assembler-x64.cc', - 'test-macro-assembler-x64.cc', - 'test-log-stack-tracer.cc', - 'test-disasm-x64.cc'], - 'arch:mips': ['test-assembler-mips.cc', - 'test-disasm-mips.cc'], - 'os:linux': ['test-platform-linux.cc'], - 'os:macos': ['test-platform-macos.cc'], - 'os:nullos': ['test-platform-nullos.cc'], - 'os:win32': ['test-platform-win32.cc'] -} - - -def Build(): - cctest_files = context.GetRelevantSources(SOURCES) - env = Environment(tools=tools) - env.Replace(**context.flags['cctest']) - context.ApplyEnvOverrides(env) - env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C) - - # Combine the JavaScript library files into a single C++ file and - # compile it. - js_files = [s for s in JS_FILES_FOR_TESTS] - js_files_src = env.JS2C( - ['js-files-for-cctest.cc'], js_files, **{'TYPE': 'TEST', 'COMPRESSION': 'off'}) - js_files_obj = context.ConfigureObject(env, js_files_src, CPPPATH=['.']) - - # There seems to be a glitch in the way scons decides where to put - # PDB files when compiling using MSVC so we specify it manually. - # This should not affect any other platforms. - object_files.append(js_files_obj) - return env.Program('cctest', ['cctest.cc', cctest_files, object_files], - PDB='cctest.exe.pdb') - - -program = Build() -Return('program') diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp index f58d958248..ecffeaa6f7 100644 --- a/deps/v8/test/cctest/cctest.gyp +++ b/deps/v8/test/cctest/cctest.gyp @@ -159,7 +159,9 @@ 'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'], }, { - 'dependencies': ['../../tools/gyp/v8.gyp:v8_nosnapshot'], + 'dependencies': [ + '../../tools/gyp/v8.gyp:v8_nosnapshot.<(v8_target_arch)', + ], }], ], }, { diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py index 4c2cd231c8..4ab5ab5b7d 100644 --- a/deps/v8/test/cctest/testcfg.py +++ b/deps/v8/test/cctest/testcfg.py @@ -84,100 +84,3 @@ class CcTestSuite(testsuite.TestSuite): def GetSuite(name, root): return CcTestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -from os.path import exists, join, normpath -import test - - -class CcTestCase(test.TestCase): - - def __init__(self, path, executable, mode, raw_name, dependency, context, variant_flags): - super(CcTestCase, self).__init__(context, path, mode) - self.executable = executable - self.raw_name = raw_name - self.dependency = dependency - self.variant_flags = variant_flags - - def GetLabel(self): - return "%s %s %s" % (self.mode, self.path[-2], self.path[-1]) - - def GetName(self): - return self.path[-1] - - def BuildCommand(self, name): - serialization_file = '' - if exists(join(self.context.buildspace, 'obj', 'test', self.mode)): - serialization_file = join('obj', 'test', self.mode, 'serdes') - else: - serialization_file = join('obj', 'serdes') - if not exists(join(self.context.buildspace, 'obj')): - os.makedirs(join(self.context.buildspace, 'obj')) - serialization_file += '_' + self.GetName() - serialization_file = join(self.context.buildspace, serialization_file) - serialization_file += ''.join(self.variant_flags).replace('-', '_') - serialization_option = '--testing_serialization_file=' + serialization_file - result = [ self.executable, name, serialization_option ] - result += self.context.GetVmFlags(self, self.mode) - return result - - def GetCommand(self): - return self.BuildCommand(self.raw_name) - - def Run(self): - if self.dependency != '': - dependent_command = self.BuildCommand(self.dependency) - output = self.RunCommand(dependent_command) - if output.HasFailed(): - return output - return test.TestCase.Run(self) - - -class CcTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(CcTestConfiguration, self).__init__(context, root) - - def GetBuildRequirements(self): - return ['cctests'] - - def ListTests(self, current_path, path, mode, variant_flags): - executable = 'cctest' - if utils.IsWindows(): - executable += '.exe' - executable = join(self.context.buildspace, executable) - if not exists(executable): - executable = join('obj', 'test', mode, 'cctest') - if utils.IsWindows(): - executable += '.exe' - executable = join(self.context.buildspace, executable) - full_command = self.context.processor([executable, '--list']) - output = test.Execute(full_command, self.context) - if output.exit_code != 0: - print output.stdout - print output.stderr - return [] - result = [] - for test_desc in output.stdout.strip().split(): - raw_test, dependency = test_desc.split('<') - relative_path = raw_test.split('/') - full_path = current_path + relative_path - if dependency != '': - dependency = relative_path[0] + '/' + dependency - if self.Contains(path, full_path): - result.append(CcTestCase(full_path, executable, mode, raw_test, dependency, self.context, variant_flags)) - result.sort() - return result - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'cctest.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return CcTestConfiguration(context, root) diff --git a/deps/v8/test/es5conform/README b/deps/v8/test/es5conform/README deleted file mode 100644 index 675249e0f1..0000000000 --- a/deps/v8/test/es5conform/README +++ /dev/null @@ -1,14 +0,0 @@ -This directory contains code for binding the es5conform test suite -into the v8 test harness. To use the tests check out the es5conform -tests from - - https://es5conform.svn.codeplex.com/svn - -in revision 71525 as 'data' in this directory. Using later version -may be possible but the tests are only known to pass (and indeed run) -with that revision. - -If you do update to a newer revision you may have to change the test -harness adapter code since it uses internal functionality from the -harness that comes bundled with the tests. You will most likely also -have to update the test expectation file. diff --git a/deps/v8/test/es5conform/es5conform.status b/deps/v8/test/es5conform/es5conform.status deleted file mode 100644 index 12ebf903e9..0000000000 --- a/deps/v8/test/es5conform/es5conform.status +++ /dev/null @@ -1,316 +0,0 @@ -# Copyright 2009 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -prefix es5conform -def UNIMPLEMENTED = PASS || FAIL -def FAIL_OK = FAIL, OKAY - - -############################################################################## -# Non UTF8 characters in test files. -chapter10/10.4/10.4.2/10.4.2-3-c-2-s: FAIL_OK -chapter10/10.4/10.4.2/10.4.2-3-c-1-s: FAIL_OK -chapter10/10.4/10.4.2/10.4.2-2-c-1: FAIL_OK - -# We do not implement the error chekcs specified in the production rules -# of 11.1.5 (Object initializer). -# We are compatible with Safari and Firefox. -chapter11/11.1/11.1.5: UNIMPLEMENTED - -# Our Function object has an "arguments" property which is used as a -# non-property in the test. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK - -# Our Function object has a "caller" property which is used as a -# non-property in in the test. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-184: FAIL_OK - -# Our function object has a name property which is used as a -# non-property in the test. -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-188: FAIL_OK - -# NOT IMPLEMENTED: RegExp.prototype.source -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212: UNIMPLEMENTED - -# NOT IMPLEMENTED: RegExp.prototype.global -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-213: UNIMPLEMENTED - -# NOT IMPLEMENTED: RegExp.prototype.ignoreCase -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214: UNIMPLEMENTED - -# NOT IMPLEMENTED: RegExp.prototype.multiline -chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: UNIMPLEMENTED - -# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because -# the tests assumes that objects can not have more properties -# than those described in the spec - but according to spec they can -# have additional properties. -# All compareArray calls in these tests could be exchanged with a -# isSubsetOfArray call (I will upload a patch to the es5conform site). - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-1: FAIL_OK - -# SUBSETFAIL + we do not implement all methods on Object. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-2: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-3: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-4: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-5: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-6: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-7: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK - -# EvalError.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-15: FAIL - -# Rangeerror.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-16: FAIL - -# ReferenceError.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-17: FAIL - -# SyntaxError.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-18: FAIL - -# TypeError.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-19: FAIL - -# URIError.prototype does not have message property. -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-20: FAIL - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-22: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-23: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-24: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-25: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-26: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-27: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-28: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-29: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-30: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-31: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-32: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-33: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-34: FAIL_OK - -# SUBSETFAIL -chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-35: FAIL_OK - -# Bad test - the test at the end should be "i === true". -chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-8-10: FAIL_OK - -# Bad test - according to spec some returns a Boolean, not a number. -chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-4-9: FAIL_OK - -# Bad test - uses unitialized variable a in precondition check. -chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-9-3: FAIL_OK - -# We do not implement Array mapping functions correctly if array -# entries are added for nonexistent entries smaller than length by -# the callback function. We are compatible with JSC. -# See http://code.google.com/p/v8/issues/detail?id=755 -chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-1: FAIL_OK - -# Bad tests, path in test file is wrong. This will crash the test -# script so we mark it SKIP. -chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4: SKIP -chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4-s: SKIP - -# Bad test - deleting the property on o in callbackfn will -# have no effect on the actual array on which reduceRight is called. -chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-7: FAIL_OK - -############################################################################## -# Unimplemented parts of strict mode -# Setting expectations to fail only so that the tests trigger as soon as -# the strict mode feature gets implemented - -# A directive preceeding an 'use strict' directive may not contain -# an OctalEscapeSequence -# Incorrect test - need double escape in eval. -chapter07/7.8/7.8.4/7.8.4-1-s: FAIL - -# arguments.caller is non-configurable in strict mode -# Invalid test case. Checks for "writable == true" and presence of "put".. -chapter10/10.6/10.6-13-b-3-s: FAIL -# arguments.callee is non-configurable in strict mode -# Invalid test case. Checks for "put" property accessor. -chapter10/10.6/10.6-13-c-3-s: FAIL - -# simple assignment throws TypeError if LeftHandSide is a property reference -# with a primitive base value (this is undefined) -chapter11/11.13/11.13.1/11.13.1-1-7-s: FAIL - -# simple assignment throws TypeError if LeftHandSide is a readonly property -# in strict mode (Global.NaN) -chapter11/11.13/11.13.1/11.13.1-4-2-s: FAIL -# simple assignment throws TypeError if LeftHandSide is a readonly property -# in strict mode (Global.Infinity) -chapter11/11.13/11.13.1/11.13.1-4-3-s: FAIL -# simple assignment throws TypeError if LeftHandSide is a readonly property -# in strict mode (Global.length) -chapter11/11.13/11.13.1/11.13.1-4-4-s: FAIL -# simple assignment throws TypeError if LeftHandSide is a readonly property -# in strict mode (Global.undefined) -chapter11/11.13/11.13.1/11.13.1-4-27-s: FAIL - -# delete operator throws TypeError when when deleting a non-configurable -# data property in strict mode (Global.NaN) -# Invalid test case - "this" is not a global object within the test case. -# (http://es5conform.codeplex.com/workitem/29151) -chapter11/11.4/11.4.1/11.4.1-4.a-4-s: FAIL_OK - -# delete operator throws ReferenceError when deleting a direct reference -# to a var in strict mode -# Invalid test case. Test expects ReferenceError instead of SyntaxError. -# http://es5conform.codeplex.com/workitem/29084 -chapter11/11.4/11.4.1/11.4.1-5-1-s: FAIL -# delete operator throws ReferenceError when deleting a direct reference -# to a function argument in strict mode -# Invalid test case. Test expects ReferenceError instead of SyntaxError. -# http://es5conform.codeplex.com/workitem/29084 -chapter11/11.4/11.4.1/11.4.1-5-2-s: FAIL -# delete operator throws ReferenceError when deleting a direct reference -# to a function name in strict mode -# Invalid test case. Test expects ReferenceError instead of SyntaxError. -# http://es5conform.codeplex.com/workitem/29084 -chapter11/11.4/11.4.1/11.4.1-5-3-s: FAIL - -# eval - a function declaring a var named 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-1-s: FAIL -# eval - a function assigning into 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-2-s: FAIL -# eval - a function expr declaring a var named 'eval' throws EvalError -# in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-3-s: FAIL -# eval - a function expr assigning into 'eval' throws a EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-4-s: FAIL -# eval - a Function declaring var named 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-5-s: FAIL -# eval - a Function assigning into 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-6-s: FAIL -# eval - a direct eval declaring a var named 'eval' throws EvalError -# in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-7-s: FAIL -# eval - a direct eval assigning into 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-8-s: FAIL -# eval - an indirect eval declaring a var named 'eval' throws EvalError -# in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-9-s: FAIL -# eval - an indirect eval assigning into 'eval' throws EvalError in strict mode -# Invalid test case. SyntaxError should be expected instead of EvalError. -chapter12/12.2/12.2.1/12.2.1-10-s: FAIL - -# SyntaxError if eval used as function identifier in function declaration -# with strict body -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-3-s: FAIL -# SyntaxError if eval used as function identifier in function expression -# with strict body -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-4-s: FAIL -# SyntaxError if eval used as function identifier in function declaration -# in strict code -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-5-s: FAIL -# SyntaxError if eval used as function identifier in function expression -# in strict code -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-6-s: FAIL -# SyntaxError if arguments used as function identifier in function declaration -# with strict body -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-9-s: FAIL -# SyntaxError if arguments used as function identifier in function expression -# with strict body -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-10-s: FAIL -# SyntaxError if arguments used as function identifier in function declaration -# in strict code -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-11-s: FAIL -# SyntaxError if arguments used as function identifier in function expression -# in strict code -# Test fails to return true on success (invalid test case). -chapter13/13.1/13.1-3-12-s: FAIL - -# Duplicate combined parameter name allowed in Function constructor called -# in strict mode if body not strict -# Test fails to return true on success (invalid test case). -chapter15/15.3/15.3.2/15.3.2.1/15.3.2.1-11-6-s: FAIL - -# Array.prototype.reduce - null passed as thisValue to strict callbackfn -# Invalid test case: http://es5conform.codeplex.com/workitem/29085 -chapter15/15.4/15.4.4/15.4.4.21/15.4.4.21-9-c-ii-4-s: FAIL diff --git a/deps/v8/test/es5conform/harness-adapt.js b/deps/v8/test/es5conform/harness-adapt.js deleted file mode 100644 index 396d4ed978..0000000000 --- a/deps/v8/test/es5conform/harness-adapt.js +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2009 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -var global = this; - -function ES5Error(ut) { - this.ut = ut; -} - -ES5Error.prototype.toString = function () { - return this.ut.res; -}; - -// The harness uses the IE specific .description property of exceptions but -// that's nothing we can't hack our way around. -Error.prototype.__defineGetter__('description', function () { - return this.message; -}); - -function TestHarness() { - sth.call(this, global); - this._testResults = [] -} - -// Borrow sth's registerTest method. -TestHarness.prototype.registerTest = sth.prototype.registerTest; - -// Drop the before/after stuff, just run the test. -TestHarness.prototype.startTesting = function () { - sth.prototype.run.call(this); - this.report(); -}; - -TestHarness.prototype.report = function () { - for (var i = 0; i < this._testResults.length; i++) { - var ut = this._testResults[i]; - // We don't fail on preconditions. Yet. - if (ut.res == "Precondition failed") - continue; - if (ut.res != 'pass') - throw new ES5Error(ut); - } -}; - -TestHarness.prototype.startingTest = function (ut) { - this.currentTest = ut; - this._testResults.push(ut); -}; - -var ES5Harness = new TestHarness(); diff --git a/deps/v8/test/es5conform/testcfg.py b/deps/v8/test/es5conform/testcfg.py deleted file mode 100644 index 7de990d387..0000000000 --- a/deps/v8/test/es5conform/testcfg.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2008 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import test -import os -from os.path import join, exists - - -def GetSuite(name, root): - # Not implemented. - return None - - -HARNESS_FILES = ['sth.js'] - - -class ES5ConformTestCase(test.TestCase): - - def __init__(self, filename, path, context, root, mode, framework): - super(ES5ConformTestCase, self).__init__(context, path, mode) - self.filename = filename - self.framework = framework - self.root = root - - def IsNegative(self): - return self.filename.endswith('-n.js') - - def GetLabel(self): - return "%s es5conform %s" % (self.mode, self.GetName()) - - def IsFailureOutput(self, output): - if output.exit_code != 0: - return True - return 'FAILED!' in output.stdout - - def GetCommand(self): - result = self.context.GetVmCommand(self, self.mode) - result += ['-e', 'var window = this'] - result += self.framework - result.append(self.filename) - result += ['-e', 'ES5Harness.startTesting()'] - return result - - def GetName(self): - return self.path[-1] - - def GetSource(self): - return open(self.filename).read() - - -class ES5ConformTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(ES5ConformTestConfiguration, self).__init__(context, root) - - def ListTests(self, current_path, path, mode, variant_flags): - tests = [] - current_root = join(self.root, 'data', 'TestCases') - harness = [] - harness += [join(self.root, 'data', 'SimpleTestHarness', f) for f in HARNESS_FILES] - harness += [join(self.root, 'harness-adapt.js')] - for root, dirs, files in os.walk(current_root): - for dotted in [x for x in dirs if x.startswith('.')]: - dirs.remove(dotted) - dirs.sort() - root_path = root[len(self.root):].split(os.path.sep) - root_path = current_path + [x for x in root_path if x] - files.sort() - for file in files: - if file.endswith('.js'): - full_path = root_path + [file[:-3]] - full_path = [x for x in full_path if not (x in ['data', 'TestCases'])] - if self.Contains(path, full_path): - test = ES5ConformTestCase(join(root, file), full_path, self.context, - self.root, mode, harness) - tests.append(test) - return tests - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'es5conform.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return ES5ConformTestConfiguration(context, root) diff --git a/deps/v8/test/message/testcfg.py b/deps/v8/test/message/testcfg.py index dba65a9a2e..11c0d19a3c 100644 --- a/deps/v8/test/message/testcfg.py +++ b/deps/v8/test/message/testcfg.py @@ -50,7 +50,7 @@ class MessageTestSuite(testsuite.TestSuite): files.sort() for filename in files: if filename.endswith(".js"): - testname = join(dirname[len(self.root) + 1:], filename[:-3]) + testname = os.path.join(dirname[len(self.root) + 1:], filename[:-3]) test = testcase.TestCase(self, testname) tests.append(test) return tests @@ -109,116 +109,3 @@ class MessageTestSuite(testsuite.TestSuite): def GetSuite(name, root): return MessageTestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -import test -from os.path import join, exists, basename, isdir - -class MessageTestCase(test.TestCase): - - def __init__(self, path, file, expected, mode, context, config): - super(MessageTestCase, self).__init__(context, path, mode) - self.file = file - self.expected = expected - self.config = config - - def IgnoreLine(self, str): - """Ignore empty lines, valgrind output and Android output.""" - if not str: return True - return (str.startswith('==') or str.startswith('**') or - str.startswith('ANDROID')) - - def IsFailureOutput(self, output): - f = file(self.expected) - # Skip initial '#' comment and spaces - for line in f: - if (not line.startswith('#')) and (not line.strip()): - break - # Convert output lines to regexps that we can match - env = { 'basename': basename(self.file) } - patterns = [ ] - for line in f: - if not line.strip(): - continue - pattern = re.escape(line.rstrip() % env) - pattern = pattern.replace('\\*', '.*') - pattern = '^%s$' % pattern - patterns.append(pattern) - # Compare actual output with the expected - raw_lines = output.stdout.splitlines() - outlines = [ s for s in raw_lines if not self.IgnoreLine(s) ] - if len(outlines) != len(patterns): - return True - for i in xrange(len(patterns)): - if not re.match(patterns[i], outlines[i]): - return True - return False - - def GetLabel(self): - return "%s %s" % (self.mode, self.GetName()) - - def GetName(self): - return self.path[-1] - - def GetCommand(self): - result = self.config.context.GetVmCommand(self, self.mode) - source = open(self.file).read() - flags_match = re.findall(FLAGS_PATTERN, source) - for match in flags_match: - result += match.strip().split() - result.append(self.file) - return result - - def GetSource(self): - return (open(self.file).read() - + "\n--- expected output ---\n" - + open(self.expected).read()) - - -class MessageTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(MessageTestConfiguration, self).__init__(context, root) - - def Ls(self, path): - if isdir(path): - return [f[:-3] for f in os.listdir(path) if f.endswith('.js')] - else: - return [] - - def ListTests(self, current_path, path, mode, variant_flags): - mjsunit = [current_path + [t] for t in self.Ls(self.root)] - regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))] - bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))] - mjsunit.sort() - regress.sort() - bugs.sort() - all_tests = mjsunit + regress + bugs - result = [] - for test in all_tests: - if self.Contains(path, test): - file_prefix = join(self.root, reduce(join, test[1:], "")) - file_path = file_prefix + ".js" - output_path = file_prefix + ".out" - if not exists(output_path): - print "Could not find %s" % output_path - continue - result.append(MessageTestCase(test, file_path, output_path, mode, - self.context, self)) - return result - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'message.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return MessageTestConfiguration(context, root) diff --git a/deps/v8/test/mjsunit/harmony/generators-objects.js b/deps/v8/test/mjsunit/harmony/generators-objects.js index 0c36818c8e..b717c303c8 100644 --- a/deps/v8/test/mjsunit/harmony/generators-objects.js +++ b/deps/v8/test/mjsunit/harmony/generators-objects.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --harmony-generators --harmony-scoping +// Flags: --harmony-generators --harmony-scoping --allow-natives-syntax // Test instantations of generators. @@ -55,6 +55,8 @@ function TestGeneratorObject() { var iter = g(); assertSame(g.prototype, Object.getPrototypeOf(iter)); assertTrue(iter instanceof g); + assertEquals("Generator", %ClassOf(iter)); + assertEquals("[object Generator]", String(iter)); assertEquals([], Object.getOwnPropertyNames(iter)); assertTrue(iter !== g()); @@ -62,7 +64,30 @@ function TestGeneratorObject() { iter = new g(); assertSame(g.prototype, Object.getPrototypeOf(iter)); assertTrue(iter instanceof g); + assertEquals("Generator", %ClassOf(iter)); + assertEquals("[object Generator]", String(iter)); assertEquals([], Object.getOwnPropertyNames(iter)); assertTrue(iter !== new g()); } TestGeneratorObject(); + + +// Test the methods of generator objects. +function TestGeneratorObjectMethods() { + function* g() { yield 1; } + var iter = g(); + + function TestNonGenerator(non_generator) { + assertThrows(function() { iter.next.call(non_generator); }, TypeError); + assertThrows(function() { iter.send.call(non_generator, 1); }, TypeError); + assertThrows(function() { iter.throw.call(non_generator, 1); }, TypeError); + assertThrows(function() { iter.close.call(non_generator); }, TypeError); + } + + TestNonGenerator(1); + TestNonGenerator({}); + TestNonGenerator(function(){}); + TestNonGenerator(g); + TestNonGenerator(g.prototype); +} +TestGeneratorObjectMethods(); diff --git a/deps/v8/test/mjsunit/harmony/typedarrays.js b/deps/v8/test/mjsunit/harmony/typedarrays.js index 75ff3da42e..7f9c7631cd 100644 --- a/deps/v8/test/mjsunit/harmony/typedarrays.js +++ b/deps/v8/test/mjsunit/harmony/typedarrays.js @@ -45,9 +45,11 @@ function TestArrayBufferCreation() { TestByteLength(0, 0); +/* TODO[dslomov]: Reenable the test assertThrows(function() { var ab1 = new __ArrayBuffer(0xFFFFFFFFFFFF) }, RangeError); +*/ var ab = new __ArrayBuffer(); assertSame(0, ab.byteLength); diff --git a/deps/v8/src/builtins-decls.h b/deps/v8/test/mjsunit/regress/regress-grow-store-smi-check.js index beb5dd1e80..381141d523 100644 --- a/deps/v8/src/builtins-decls.h +++ b/deps/v8/test/mjsunit/regress/regress-grow-store-smi-check.js @@ -25,16 +25,29 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef V8_BUILTINS_DECLS_H_ -#define V8_BUILTINS_DECLS_H_ +// Flags: --allow-natives-syntax -#include "arguments.h" +// The below test function was generated from part of a WebKit layout +// test library setup routine: fast/canvas/webgl/resources/pnglib.js -namespace v8 { -namespace internal { +function test(crc32) { + for (var i = 0; i < 256; i++) { + var c = i; + for (var j = 0; j < 8; j++) { + if (c & 1) { + c = -306674912 ^ ((c >> 1) & 0x7fffffff); + } else { + c = (c >> 1) & 0x7fffffff; + } + } + crc32[i] = c; + } +} -DECLARE_RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure); +var a = [0.5]; +for (var i = 0; i < 256; ++i) a[i] = i; -} } // namespace v8::internal - -#endif // V8_BUILTINS_DECLS_H_ +test([0.5]); +test(a); +%OptimizeFunctionOnNextCall(test); +test(a); diff --git a/deps/v8/test/mjsunit/string-fromcharcode.js b/deps/v8/test/mjsunit/string-fromcharcode.js index 1986dda0fb..631c04349f 100644 --- a/deps/v8/test/mjsunit/string-fromcharcode.js +++ b/deps/v8/test/mjsunit/string-fromcharcode.js @@ -25,8 +25,29 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --allow-natives-syntax + // Test String.fromCharCode. +// Test char codes larger than 0xffff. +var expected = ""; +for (var i = 100; i < 500; i++) { + expected += String.fromCharCode(i); +} + +function testCharCodeTruncation() { + var result = ""; + for (var i = 0x100000 + 100; i < 0x100000 + 500; i++) { + result += String.fromCharCode(i); + } + assertEquals(String.fromCharCode(0xFFFF), String.fromCharCode(0xFFFFFFFF)); + return result; +} + +assertEquals(expected, testCharCodeTruncation()); +assertEquals(expected, testCharCodeTruncation()); +%OptimizeFunctionOnNextCall(testCharCodeTruncation); +assertEquals(expected, testCharCodeTruncation()); // Test various receivers and arguments passed to String.fromCharCode. diff --git a/deps/v8/test/mjsunit/testcfg.py b/deps/v8/test/mjsunit/testcfg.py index 00d4500f1c..c960ce6b30 100644 --- a/deps/v8/test/mjsunit/testcfg.py +++ b/deps/v8/test/mjsunit/testcfg.py @@ -50,7 +50,7 @@ class MjsunitTestSuite(testsuite.TestSuite): files.sort() for filename in files: if filename.endswith(".js") and filename != "mjsunit.js": - testname = join(dirname[len(self.root) + 1:], filename[:-3]) + testname = os.path.join(dirname[len(self.root) + 1:], filename[:-3]) test = testcase.TestCase(self, testname) tests.append(test) return tests @@ -95,134 +95,3 @@ class MjsunitTestSuite(testsuite.TestSuite): def GetSuite(name, root): return MjsunitTestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -from os.path import dirname, exists, join, normpath -import tempfile -import test - - -class MjsunitTestCase(test.TestCase): - - def __init__(self, path, file, mode, context, config, isolates): - super(MjsunitTestCase, self).__init__(context, path, mode) - self.file = file - self.config = config - self.self_script = False - self.isolates = isolates - - def GetLabel(self): - return "%s %s" % (self.mode, self.GetName()) - - def GetName(self): - return self.path[-1] + ["", "-isolates"][self.isolates] - - def TestsIsolates(self): - return self.isolates - - def GetVmCommand(self, source): - result = self.config.context.GetVmCommand(self, self.mode) - flags_match = re.findall(FLAGS_PATTERN, source); - for match in flags_match: - result += match.strip().split() - return result - - def GetVmArguments(self, source): - result = [] - additional_files = [] - files_match = FILES_PATTERN.search(source); - # Accept several lines of 'Files:' - while True: - if files_match: - additional_files += files_match.group(1).strip().split() - files_match = FILES_PATTERN.search(source, files_match.end()) - else: - break - for a_file in additional_files: - result.append(join(dirname(self.config.root), '..', a_file)) - framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js') - if SELF_SCRIPT_PATTERN.search(source): - result.append(self.CreateSelfScript()) - result += [framework, self.file] - return result - - def GetCommand(self): - source = open(self.file).read() - result = self.GetVmCommand(source) - result += self.GetVmArguments(source) - if self.isolates: - result.append("--isolate") - result += self.GetVmArguments(source) - return result - - def GetSource(self): - return open(self.file).read() - - def CreateSelfScript(self): - (fd_self_script, self_script) = tempfile.mkstemp(suffix=".js") - def MakeJsConst(name, value): - return "var %(name)s=\'%(value)s\';\n" % \ - {'name': name, \ - 'value': value.replace('\\', '\\\\').replace('\'', '\\\'') } - try: - os.write(fd_self_script, MakeJsConst('TEST_FILE_NAME', self.file)) - except IOError, e: - test.PrintError("write() " + str(e)) - os.close(fd_self_script) - self.self_script = self_script - return self_script - - def AfterRun(self, result): - if self.self_script and (not result or (not result.HasPreciousOutput())): - test.CheckedUnlink(self.self_script) - -class MjsunitTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(MjsunitTestConfiguration, self).__init__(context, root) - - def Ls(self, path): - def SelectTest(name): - return name.endswith('.js') and name != 'mjsunit.js' - return [f[:-3] for f in os.listdir(path) if SelectTest(f)] - - def ListTests(self, current_path, path, mode, variant_flags): - mjsunit = [current_path + [t] for t in self.Ls(self.root)] - regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))] - bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))] - third_party = [current_path + ['third_party', t] for t in self.Ls(join(self.root, 'third_party'))] - tools = [current_path + ['tools', t] for t in self.Ls(join(self.root, 'tools'))] - compiler = [current_path + ['compiler', t] for t in self.Ls(join(self.root, 'compiler'))] - harmony = [current_path + ['harmony', t] for t in self.Ls(join(self.root, 'harmony'))] - mjsunit.sort() - regress.sort() - bugs.sort() - third_party.sort() - tools.sort() - compiler.sort() - harmony.sort() - all_tests = mjsunit + regress + bugs + third_party + tools + compiler + harmony - result = [] - for test in all_tests: - if self.Contains(path, test): - file_path = join(self.root, reduce(join, test[1:], "") + ".js") - result.append(MjsunitTestCase(test, file_path, mode, self.context, self, False)) - result.append(MjsunitTestCase(test, file_path, mode, self.context, self, True)) - return result - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'mjsunit.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - - -def GetConfiguration(context, root): - return MjsunitTestConfiguration(context, root) diff --git a/deps/v8/test/mozilla/testcfg.py b/deps/v8/test/mozilla/testcfg.py index 5aeac4cc67..775a239f07 100644 --- a/deps/v8/test/mozilla/testcfg.py +++ b/deps/v8/test/mozilla/testcfg.py @@ -104,7 +104,7 @@ class MozillaTestSuite(testsuite.TestSuite): return testcase.flags + result def GetSourceForTest(self, testcase): - filename = join(self.testroot, testcase.path + ".js") + filename = os.path.join(self.testroot, testcase.path + ".js") with open(filename) as f: return f.read() @@ -150,7 +150,7 @@ class MozillaTestSuite(testsuite.TestSuite): if code != 0: os.chdir(old_cwd) raise Exception("Error checking out Mozilla test suite!") - os.rename(join("mozilla", "js", "tests"), directory_name) + os.rename(os.path.join("mozilla", "js", "tests"), directory_name) shutil.rmtree("mozilla") with tarfile.open(archive_file, "w:gz") as tar: tar.add("data") @@ -161,96 +161,3 @@ class MozillaTestSuite(testsuite.TestSuite): def GetSuite(name, root): return MozillaTestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -from os.path import exists -from os.path import join -import test - - -class MozillaTestCase(test.TestCase): - - def __init__(self, filename, path, context, root, mode, framework): - super(MozillaTestCase, self).__init__(context, path, mode) - self.filename = filename - self.framework = framework - self.root = root - - def IsNegative(self): - return self.filename.endswith('-n.js') - - def GetLabel(self): - return "%s mozilla %s" % (self.mode, self.GetName()) - - def IsFailureOutput(self, output): - if output.exit_code != 0: - return True - return 'FAILED!' in output.stdout - - def GetCommand(self): - result = self.context.GetVmCommand(self, self.mode) + \ - [ '--expose-gc', join(self.root, 'mozilla-shell-emulation.js') ] - result += [ '--es5_readonly' ] # Temporary hack until we can remove flag - result += self.framework - result.append(self.filename) - return result - - def GetName(self): - return self.path[-1] - - def GetSource(self): - return open(self.filename).read() - - -class MozillaTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(MozillaTestConfiguration, self).__init__(context, root) - - def ListTests(self, current_path, path, mode, variant_flags): - tests = [] - for test_dir in TEST_DIRS: - current_root = join(self.root, 'data', test_dir) - for root, dirs, files in os.walk(current_root): - for dotted in [x for x in dirs if x.startswith('.')]: - dirs.remove(dotted) - for excluded in EXCLUDED: - if excluded in dirs: - dirs.remove(excluded) - dirs.sort() - root_path = root[len(self.root):].split(os.path.sep) - root_path = current_path + [x for x in root_path if x] - framework = [] - for i in xrange(len(root_path)): - if i == 0: dir = root_path[1:] - else: dir = root_path[1:-i] - script = join(self.root, reduce(join, dir, ''), 'shell.js') - if exists(script): - framework.append(script) - framework.reverse() - files.sort() - for file in files: - if (not file in FRAMEWORK) and file.endswith('.js'): - full_path = root_path + [file[:-3]] - full_path = [x for x in full_path if x != 'data'] - if self.Contains(path, full_path): - test = MozillaTestCase(join(root, file), full_path, self.context, - self.root, mode, framework) - tests.append(test) - return tests - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'mozilla.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return MozillaTestConfiguration(context, root) diff --git a/deps/v8/test/preparser/testcfg.py b/deps/v8/test/preparser/testcfg.py index 61c14c9bd3..566fd5ca44 100644 --- a/deps/v8/test/preparser/testcfg.py +++ b/deps/v8/test/preparser/testcfg.py @@ -42,7 +42,7 @@ class PreparserTestSuite(testsuite.TestSuite): return "preparser" def _GetExpectations(self): - expects_file = join(self.root, "preparser.expectation") + expects_file = os.path.join(self.root, "preparser.expectation") expectations_map = {} if not os.path.exists(expects_file): return expectations_map rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$") @@ -58,7 +58,7 @@ class PreparserTestSuite(testsuite.TestSuite): return expectations_map def _ParsePythonTestTemplates(self, result, filename): - pathname = join(self.root, filename + ".pyt") + pathname = os.path.join(self.root, filename + ".pyt") def Test(name, source, expectation): source = source.replace("\n", " ") testname = os.path.join(filename, name) @@ -118,143 +118,3 @@ class PreparserTestSuite(testsuite.TestSuite): def GetSuite(name, root): return PreparserTestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -from os.path import join, exists, isfile -import test - - -class PreparserTestCase(test.TestCase): - - def __init__(self, root, path, executable, mode, throws, context, source): - super(PreparserTestCase, self).__init__(context, path, mode) - self.executable = executable - self.root = root - self.throws = throws - self.source = source - - def GetLabel(self): - return "%s %s %s" % (self.mode, self.path[-2], self.path[-1]) - - def GetName(self): - return self.path[-1] - - def HasSource(self): - return self.source is not None - - def GetSource(self): - return self.source - - def BuildCommand(self, path): - if (self.source is not None): - result = [self.executable, "-e", self.source] - else: - testfile = join(self.root, self.GetName()) + ".js" - result = [self.executable, testfile] - if (self.throws): - result += ['throws'] + self.throws - return result - - def GetCommand(self): - return self.BuildCommand(self.path) - - def Run(self): - return test.TestCase.Run(self) - - -class PreparserTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(PreparserTestConfiguration, self).__init__(context, root) - - def GetBuildRequirements(self): - return ['preparser'] - - def GetExpectations(self): - expects_file = join(self.root, 'preparser.expectation') - map = {} - if exists(expects_file): - rule_regex = re.compile("^([\w\-]+)(?::([\w\-]+))?(?::(\d+),(\d+))?$") - for line in utils.ReadLinesFrom(expects_file): - if (line[0] == '#'): continue - rule_match = rule_regex.match(line) - if rule_match: - expects = [] - if (rule_match.group(2)): - expects = expects + [rule_match.group(2)] - if (rule_match.group(3)): - expects = expects + [rule_match.group(3), rule_match.group(4)] - map[rule_match.group(1)] = expects - return map; - - def ParsePythonTestTemplates(self, result, filename, - executable, current_path, mode): - pathname = join(self.root, filename + ".pyt") - def Test(name, source, expectation): - throws = None - if (expectation is not None): - throws = [expectation] - test = PreparserTestCase(self.root, - current_path + [filename, name], - executable, - mode, throws, self.context, - source.replace("\n", " ")) - result.append(test) - def Template(name, source): - def MkTest(replacement, expectation): - testname = name - testsource = source - for key in replacement.keys(): - testname = testname.replace("$"+key, replacement[key]); - testsource = testsource.replace("$"+key, replacement[key]); - Test(testname, testsource, expectation) - return MkTest - execfile(pathname, {"Test": Test, "Template": Template}) - - def ListTests(self, current_path, path, mode, variant_flags): - executable = 'preparser' - if utils.IsWindows(): - executable += '.exe' - executable = join(self.context.buildspace, executable) - if not isfile(executable): - executable = join('obj', 'preparser', mode, 'preparser') - if utils.IsWindows(): - executable += '.exe' - executable = join(self.context.buildspace, executable) - expectations = self.GetExpectations() - result = [] - # Find all .js files in tests/preparser directory. - filenames = [f[:-3] for f in os.listdir(self.root) if f.endswith(".js")] - filenames.sort() - for file in filenames: - throws = None; - if (file in expectations): - throws = expectations[file] - result.append(PreparserTestCase(self.root, - current_path + [file], executable, - mode, throws, self.context, None)) - # Find all .pyt files in test/preparser directory. - filenames = [f[:-4] for f in os.listdir(self.root) if f.endswith(".pyt")] - filenames.sort() - for file in filenames: - # Each file as a python source file to be executed in a specially - # created environment (defining the Template and Test functions) - self.ParsePythonTestTemplates(result, file, - executable, current_path, mode) - return result - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'preparser.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - def VariantFlags(self): - return [[]]; - - -def GetConfiguration(context, root): - return PreparserTestConfiguration(context, root) diff --git a/deps/v8/test/sputnik/README b/deps/v8/test/sputnik/README deleted file mode 100644 index 36566340e1..0000000000 --- a/deps/v8/test/sputnik/README +++ /dev/null @@ -1,6 +0,0 @@ -To run the sputniktests you must check out the test suite from -googlecode.com. The test expectations are currently relative to -version 97. To get the tests run the following command within -v8/test/sputnik/ - - svn co http://sputniktests.googlecode.com/svn/trunk/ -r97 sputniktests diff --git a/deps/v8/test/sputnik/sputnik.status b/deps/v8/test/sputnik/sputnik.status deleted file mode 100644 index 67d1c75fe1..0000000000 --- a/deps/v8/test/sputnik/sputnik.status +++ /dev/null @@ -1,231 +0,0 @@ -# Copyright 2009 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -prefix sputnik -def FAIL_OK = FAIL, OKAY - -############################### BUGS ################################### - -# '__proto__' should be treated as a normal property in JSON. -S15.12.2_A1: FAIL - -##################### DELIBERATE INCOMPATIBILITIES ##################### - -# This tests precision of trignometric functions. We're slightly off -# from the implementation in libc (~ 1e-17) but it's not clear if we -# or they are closer to the right answer, or if it even matters. -S15.8.2.16_A7: PASS || FAIL_OK -S15.8.2.18_A7: PASS || FAIL_OK -S15.8.2.13_A23: PASS || FAIL_OK - -# Sputnik tests (r97) assume RegExp.prototype is an Object, not a RegExp. -S15.10.6_A2: FAIL_OK - -# We are silent in some regexp cases where the spec wants us to give -# errors, for compatibility. -S15.10.2.11_A1_T2: FAIL -S15.10.2.11_A1_T3: FAIL - -# We are more lenient in which string character escapes we allow than -# the spec (7.8.4 p. 19) wants us to be. This is for compatibility. -S7.8.4_A4.3_T1: FAIL_OK -S7.8.4_A4.3_T2: FAIL_OK -S7.8.4_A4.3_T3: FAIL_OK -S7.8.4_A4.3_T4: FAIL_OK -S7.8.4_A6.4_T1: FAIL_OK -S7.8.4_A6.4_T2: FAIL_OK -S7.8.4_A7.4_T1: FAIL_OK -S7.8.4_A7.4_T2: FAIL_OK - -# Sputnik expects unicode escape sequences in RegExp flags to be interpreted. -# The specification requires them to be passed uninterpreted to the RegExp -# constructor. We now implement that. -S7.8.5_A3.1_T7: FAIL_OK -S7.8.5_A3.1_T8: FAIL_OK -S7.8.5_A3.1_T9: FAIL_OK - -# We allow some keywords to be used as identifiers. -S7.5.3_A1.15: FAIL_OK -S7.5.3_A1.18: FAIL_OK -S7.5.3_A1.21: FAIL_OK -S7.5.3_A1.22: FAIL_OK -S7.5.3_A1.23: FAIL_OK -S7.5.3_A1.24: FAIL_OK -S7.5.3_A1.26: FAIL_OK - -# This checks for non-262 behavior -S12.6.4_A14_T1: PASS || FAIL_OK -S12.6.4_R1: PASS || FAIL_OK -S12.6.4_R2: PASS || FAIL_OK -S8.4_D2.1: PASS || FAIL_OK -S8.4_D2.2: PASS || FAIL_OK -S8.4_D2.3: PASS || FAIL_OK -S8.4_D2.4: PASS || FAIL_OK -S8.4_D2.5: PASS || FAIL_OK -S8.4_D2.6: PASS || FAIL_OK -S8.4_D2.7: PASS || FAIL_OK -S8.4_D1.1: PASS || FAIL_OK -S13.2_D1.2: PASS || FAIL_OK -S11.4.3_D1.2: PASS || FAIL_OK -S7.6_D1: PASS || FAIL_OK -S7.6_D2: PASS || FAIL_OK -S15.1.2.2_D1.2: PASS || FAIL_OK -S13_D1_T1: PASS || FAIL_OK -S14_D4_T3: PASS || FAIL_OK -S14_D7: PASS || FAIL_OK -S15.5.4.11_D1.1_T2: PASS || FAIL_OK -S15.5.4.11_D1.1_T4: PASS || FAIL_OK -S15.5.2_D2: PASS || FAIL_OK -S15.5.4.11_D1.1_T1: PASS || FAIL_OK -S15.5.4.11_D1.1_T3: PASS || FAIL_OK -S12.6.4_D1: PASS || FAIL_OK -S15.5.4.14_A1_T6: FAIL_OK -S15.5.4.14_A1_T7: FAIL_OK -S15.5.4.14_A1_T8: FAIL_OK -S15.5.4.14_A1_T9: FAIL_OK -S15.5.4.14_A2_T7: FAIL_OK -S15.10.2.12_A1_T1: FAIL_OK -S15.10.2.12_A2_T1: FAIL_OK - -# We allow function declarations within statements -S12.6.2_A13_T1: FAIL_OK -S12.6.2_A13_T2: FAIL_OK -S12.6.4_A13_T1: FAIL_OK -S12.6.4_A13_T2: FAIL_OK -#S12.6.4_A13_T3: FAIL_OK -S15.3.4.2_A1_T1: FAIL_OK - -# Linux and Mac defaults to extended 80 bit floating point format in the FPU. -# We follow the other major JS engines by keeping this default. -S8.5_A2.2: PASS, FAIL if $system == linux, FAIL if $system == macos -S8.5_A2.1: PASS, FAIL if $system == linux, FAIL if $system == macos - -# The source field of RegExp objects is properly escaped. We match JSC. -S15.10.4.1_A3_T1: FAIL_OK -S15.10.4.1_A3_T2: FAIL_OK -S15.10.4.1_A3_T3: FAIL_OK -S15.10.4.1_A3_T4: FAIL_OK -S15.10.4.1_A3_T5: FAIL_OK -S15.10.4.1_A4_T2: FAIL_OK -S15.10.4.1_A4_T3: FAIL_OK -S15.10.4.1_A4_T5: FAIL_OK - -##################### ES3 TESTS ######################### -# These tests check for ES3 semantics, and differ from ES5. -# When we follow ES5 semantics, it's ok to fail the test. - -# Allow keywords as names of properties in object initialisers and -# in dot-notation property access. -S11.1.5_A4.1: FAIL_OK -S11.1.5_A4.2: FAIL_OK - -# Don't throw type errors when iterating through the undefined object. -S9.9_A1: FAIL_OK -S9.9_A2: FAIL_OK - -# The expected evaluation order of comparison operations changed. -S11.8.2_A2.3_T1: FAIL_OK -S11.8.3_A2.3_T1: FAIL_OK - -# Calls builtins without an explicit receiver which means that -# undefined is passed to the builtin. The tests expect the global -# object to be passed which was true in ES3 but not in ES5. -S11.1.1_A2: FAIL_OK -S15.5.4.4_A1_T3: FAIL_OK -S15.5.4.5_A1_T3: FAIL_OK -S15.5.4.6_A1_T3: FAIL_OK -S15.5.4.7_A1_T3: FAIL_OK -S15.5.4.8_A1_T3: FAIL_OK -S15.5.4.9_A1_T3: FAIL_OK -S15.5.4.10_A1_T3: FAIL_OK -S15.5.4.11_A1_T3: FAIL_OK -S15.5.4.12_A1_T3: FAIL_OK -S15.5.4.13_A1_T3: FAIL_OK -S15.5.4.14_A1_T3: FAIL_OK -S15.5.4.15_A1_T3: FAIL_OK - -# NaN, Infinity and undefined are read-only according to ES5. -S15.1.1.1_A2_T1: FAIL_OK # NaN -S15.1.1.1_A2_T2: FAIL_OK # NaN -S15.1.1.2_A2_T1: FAIL_OK # Infinity -# S15.1.1.2_A2_T2 would fail if it weren't bogus in r97. sputnik bug #45. -S15.1.1.3_A2_T1: FAIL_OK # undefined -S15.1.1.3_A2_T2: FAIL_OK # undefined - -# Function.prototype.apply can handle arbitrary object as argument list. -S15.3.4.3_A6_T1: FAIL_OK -S15.3.4.3_A6_T4: FAIL_OK - -# Array.prototype.to[Locale]String is generic in ES5. -S15.4.4.2_A2_T1: FAIL_OK -S15.4.4.3_A2_T1: FAIL_OK - -##################### SKIPPED TESTS ##################### - -# These tests take a looong time to run in debug mode. -S15.1.3.2_A2.5_T1: PASS, SKIP if $mode == debug -S15.1.3.1_A2.5_T1: PASS, SKIP if $mode == debug - -# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1196 -S8.7_A5_T2: FAIL - -# Invalid test case (recent change adding var changes semantics) -S8.3_A1_T1: FAIL -# Test bug: http://code.google.com/p/sputniktests/issues/detail?id=35 -S15.5.4.8_A1_T1: FAIL -# Invalid test case (recent change adding var changes semantics) -S15.3_A3_T1: FAIL -# Invalid test case (recent change adding var changes semantics) -S15.3_A3_T3: FAIL - -[ $arch == arm ] - -# BUG(3251225): Tests that timeout with --nocrankshaft. -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP -S15.1.3.1_A2.4_T1: SKIP -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.4_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP -S15.1.3.3_A2.3_T1: SKIP -S15.1.3.4_A2.3_T1: SKIP -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP - -[ $arch == mipsel ] - -# BUG(3251225): Tests that timeout with --nocrankshaft. -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP -S15.1.3.1_A2.4_T1: SKIP -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.4_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP -S15.1.3.3_A2.3_T1: SKIP -S15.1.3.4_A2.3_T1: SKIP -S15.1.3.1_A2.5_T1: SKIP -S15.1.3.2_A2.5_T1: SKIP diff --git a/deps/v8/test/sputnik/testcfg.py b/deps/v8/test/sputnik/testcfg.py deleted file mode 100644 index b6f374667c..0000000000 --- a/deps/v8/test/sputnik/testcfg.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright 2009 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import os -from os.path import join, exists -import sys -import test -import time - - -def GetSuite(name, root): - # Not implemented. - return None - - -class SputnikTestCase(test.TestCase): - - def __init__(self, case, path, context, mode): - super(SputnikTestCase, self).__init__(context, path, mode) - self.case = case - self.tmpfile = None - self.source = None - - def IsNegative(self): - return '@negative' in self.GetSource() - - def IsFailureOutput(self, output): - if output.exit_code != 0: - return True - out = output.stdout - return "SputnikError" in out - - def BeforeRun(self): - self.tmpfile = sputnik.TempFile(suffix='.js', prefix='sputnik-', text=True) - self.tmpfile.Write(self.GetSource()) - self.tmpfile.Close() - - def AfterRun(self, result): - # Dispose the temporary file if everything looks okay. - if result is None or not result.HasPreciousOutput(): self.tmpfile.Dispose() - self.tmpfile = None - - def GetCommand(self): - result = self.context.GetVmCommand(self, self.mode) - result.append(self.tmpfile.name) - return result - - def GetLabel(self): - return "%s sputnik %s" % (self.mode, self.GetName()) - - def GetName(self): - return self.path[-1] - - def GetSource(self): - if not self.source: - self.source = self.case.GetSource() - return self.source - -class SputnikTestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(SputnikTestConfiguration, self).__init__(context, root) - - def ListTests(self, current_path, path, mode, variant_flags): - # Import the sputnik test runner script as a module - testroot = join(self.root, 'sputniktests') - modroot = join(testroot, 'tools') - sys.path.append(modroot) - import sputnik - globals()['sputnik'] = sputnik - # Do not run strict mode tests yet. TODO(mmaly) - test_suite = sputnik.TestSuite(testroot, False) - test_suite.Validate() - tests = test_suite.EnumerateTests([]) - result = [] - for test in tests: - full_path = current_path + [test.GetPath()[-1]] - if self.Contains(path, full_path): - case = SputnikTestCase(test, full_path, self.context, mode) - result.append(case) - return result - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'sputnik.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return SputnikTestConfiguration(context, root) diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py index f937442f5d..c07c30270c 100644 --- a/deps/v8/test/test262/testcfg.py +++ b/deps/v8/test/test262/testcfg.py @@ -121,115 +121,3 @@ class Test262TestSuite(testsuite.TestSuite): def GetSuite(name, root): return Test262TestSuite(name, root) - - -# Deprecated definitions below. -# TODO(jkummerow): Remove when SCons is no longer supported. - - -from os.path import exists -from os.path import join -import test - - -class Test262TestCase(test.TestCase): - - def __init__(self, filename, path, context, root, mode, framework): - super(Test262TestCase, self).__init__(context, path, mode) - self.filename = filename - self.framework = framework - self.root = root - - def IsNegative(self): - return '@negative' in self.GetSource() - - def GetLabel(self): - return "%s test262 %s" % (self.mode, self.GetName()) - - def IsFailureOutput(self, output): - if output.exit_code != 0: - return True - return 'FAILED!' in output.stdout - - def GetCommand(self): - result = self.context.GetVmCommand(self, self.mode) - result += [ '--es5_readonly' ] # Temporary hack until we can remove flag - result += self.framework - result.append(self.filename) - return result - - def GetName(self): - return self.path[-1] - - def GetSource(self): - return open(self.filename).read() - - -class Test262TestConfiguration(test.TestConfiguration): - - def __init__(self, context, root): - super(Test262TestConfiguration, self).__init__(context, root) - - def ListTests(self, current_path, path, mode, variant_flags): - testroot = join(self.root, 'data', 'test', 'suite') - harness = [join(self.root, 'data', 'test', 'harness', f) - for f in TEST_262_HARNESS] - harness += [join(self.root, 'harness-adapt.js')] - tests = [] - for root, dirs, files in os.walk(testroot): - for dotted in [x for x in dirs if x.startswith('.')]: - dirs.remove(dotted) - for skipped in [x for x in dirs if x in TEST_262_SKIP]: - dirs.remove(skipped) - dirs.sort() - root_path = root[len(self.root):].split(os.path.sep) - root_path = current_path + [x for x in root_path if x] - files.sort() - for file in files: - if file.endswith('.js'): - test_path = ['test262', file[:-3]] - if self.Contains(path, test_path): - test = Test262TestCase(join(root, file), test_path, self.context, - self.root, mode, harness) - tests.append(test) - return tests - - def DownloadData(self): - revision = TEST_262_ARCHIVE_REVISION - archive_url = TEST_262_URL % revision - archive_name = join(self.root, 'test262-%s.tar.bz2' % revision) - directory_name = join(self.root, 'data') - directory_old_name = join(self.root, 'data.old') - if not exists(archive_name): - print "Downloading test data from %s ..." % archive_url - urllib.urlretrieve(archive_url, archive_name) - if exists(directory_name): - os.rename(directory_name, directory_old_name) - if not exists(directory_name): - print "Extracting test262-%s.tar.bz2 ..." % revision - md5 = hashlib.md5() - with open(archive_name,'rb') as f: - for chunk in iter(lambda: f.read(8192), ''): - md5.update(chunk) - if md5.hexdigest() != TEST_262_ARCHIVE_MD5: - os.remove(archive_name) - raise Exception("Hash mismatch of test data file") - archive = tarfile.open(archive_name, 'r:bz2') - if sys.platform in ('win32', 'cygwin'): - # Magic incantation to allow longer path names on Windows. - archive.extractall(u'\\\\?\\%s' % self.root) - else: - archive.extractall(self.root) - os.rename(join(self.root, 'test262-%s' % revision), directory_name) - - def GetBuildRequirements(self): - return ['d8'] - - def GetTestStatus(self, sections, defs): - status_file = join(self.root, 'test262.status') - if exists(status_file): - test.ReadConfigurationInto(status_file, sections, defs) - - -def GetConfiguration(context, root): - return Test262TestConfiguration(context, root) diff --git a/deps/v8/tools/test-wrapper-gypbuild.py b/deps/v8/tools/test-wrapper-gypbuild.py deleted file mode 100755 index 4dd6338dc9..0000000000 --- a/deps/v8/tools/test-wrapper-gypbuild.py +++ /dev/null @@ -1,270 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -# This is a convenience script to run the existing tools/test.py script -# when using the gyp/make based build. -# It is intended as a stop-gap rather than a long-term solution. - - -import optparse -import os -from os.path import join, dirname, abspath -import subprocess -import sys - - -PROGRESS_INDICATORS = ['verbose', 'dots', 'color', 'mono'] - - -def BuildOptions(): - result = optparse.OptionParser() - - # Flags specific to this wrapper script: - result.add_option("--arch-and-mode", - help='Architecture and mode in the format "arch.mode"', - default=None) - result.add_option("--outdir", - help='Base output directory', - default='out') - result.add_option("--no-presubmit", - help='Skip presubmit checks', - default=False, action="store_true") - result.add_option("--buildbot", - help='Adapt to path structure used on buildbots', - default=False, action="store_true") - - # Flags this wrapper script handles itself: - result.add_option("-m", "--mode", - help="The test modes in which to run (comma-separated)", - default='release,debug') - result.add_option("--arch", - help='The architectures to run tests for (comma-separated)', - default='ia32,x64,arm') - - # Flags that are passed on to the wrapped test.py script: - result.add_option("-v", "--verbose", help="Verbose output", - default=False, action="store_true") - result.add_option("-p", "--progress", - help="The style of progress indicator (verbose, dots, color, mono)", - choices=PROGRESS_INDICATORS, default="mono") - result.add_option("--report", help="Print a summary of the tests to be run", - default=False, action="store_true") - result.add_option("--download-data", help="Download missing test suite data", - default=False, action="store_true") - result.add_option("-s", "--suite", help="A test suite", - default=[], action="append") - result.add_option("-t", "--timeout", help="Timeout in seconds", - default=60, type="int") - result.add_option("--snapshot", help="Run the tests with snapshot turned on", - default=False, action="store_true") - result.add_option("--special-command", default=None) - result.add_option("--valgrind", help="Run tests through valgrind", - default=False, action="store_true") - result.add_option("--cat", help="Print the source of the tests", - default=False, action="store_true") - result.add_option("--warn-unused", help="Report unused rules", - default=False, action="store_true") - result.add_option("-j", help="The number of parallel tasks to run", - default=1, type="int") - result.add_option("--time", help="Print timing information after running", - default=False, action="store_true") - result.add_option("--suppress-dialogs", - help="Suppress Windows dialogs for crashing tests", - dest="suppress_dialogs", default=True, action="store_true") - result.add_option("--no-suppress-dialogs", - help="Display Windows dialogs for crashing tests", - dest="suppress_dialogs", action="store_false") - result.add_option("--isolates", help="Whether to test isolates", - default=False, action="store_true") - result.add_option("--store-unexpected-output", - help="Store the temporary JS files from tests that fails", - dest="store_unexpected_output", default=True, action="store_true") - result.add_option("--no-store-unexpected-output", - help="Deletes the temporary JS files from tests that fails", - dest="store_unexpected_output", action="store_false") - result.add_option("--stress-only", - help="Only run tests with --always-opt --stress-opt", - default=False, action="store_true") - result.add_option("--nostress", - help="Don't run crankshaft --always-opt --stress-op test", - default=False, action="store_true") - result.add_option("--shard-count", - help="Split testsuites into this number of shards", - default=1, type="int") - result.add_option("--shard-run", - help="Run this shard from the split up tests.", - default=1, type="int") - result.add_option("--noprof", help="Disable profiling support", - default=False) - - # Flags present in the original test.py that are unsupported in this wrapper: - # -S [-> scons_flags] (we build with gyp/make, not scons) - # --no-build (always true) - # --build-only (always false) - # --build-system (always 'gyp') - # --simulator (always true if arch==arm, always false otherwise) - # --shell (automatically chosen depending on arch and mode) - - return result - - -def ProcessOptions(options): - if options.arch_and_mode == ".": - options.arch = [] - options.mode = [] - else: - if options.arch_and_mode != None and options.arch_and_mode != "": - tokens = options.arch_and_mode.split(".") - options.arch = tokens[0] - options.mode = tokens[1] - options.mode = options.mode.split(',') - options.arch = options.arch.split(',') - for mode in options.mode: - if not mode.lower() in ['debug', 'release']: - print "Unknown mode %s" % mode - return False - for arch in options.arch: - if not arch in ['ia32', 'x64', 'arm', 'mipsel', 'android_arm', - 'android_ia32']: - print "Unknown architecture %s" % arch - return False - if options.buildbot: - # Buildbots run presubmit tests as a separate step. - options.no_presubmit = True - return True - - -def PassOnOptions(options): - result = [] - if options.verbose: - result += ['--verbose'] - if options.progress != 'mono': - result += ['--progress=' + options.progress] - if options.report: - result += ['--report'] - if options.download_data: - result += ['--download-data'] - if options.suite != []: - for suite in options.suite: - result += ['--suite=../../test/' + suite] - if options.timeout != 60: - result += ['--timeout=%s' % options.timeout] - if options.snapshot: - result += ['--snapshot'] - if options.special_command: - result += ['--special-command="%s"' % options.special_command] - if options.valgrind: - result += ['--valgrind'] - if options.cat: - result += ['--cat'] - if options.warn_unused: - result += ['--warn-unused'] - if options.j != 1: - result += ['-j%s' % options.j] - if options.time: - result += ['--time'] - if not options.suppress_dialogs: - result += ['--no-suppress-dialogs'] - if options.isolates: - result += ['--isolates'] - if not options.store_unexpected_output: - result += ['--no-store-unexpected_output'] - if options.stress_only: - result += ['--stress-only'] - if options.nostress: - result += ['--nostress'] - if options.shard_count != 1: - result += ['--shard-count=%s' % options.shard_count] - if options.shard_run != 1: - result += ['--shard-run=%s' % options.shard_run] - if options.noprof: - result += ['--noprof'] - return result - - -def Main(): - parser = BuildOptions() - (options, args) = parser.parse_args() - if not ProcessOptions(options): - parser.print_help() - return 1 - - workspace = abspath(join(dirname(sys.argv[0]), '..')) - returncodes = 0 - - if not options.no_presubmit: - print ">>> running presubmit tests" - returncodes += subprocess.call([sys.executable, - workspace + '/tools/presubmit.py']) - - args_for_children = [sys.executable] - args_for_children += [workspace + '/tools/test.py'] + PassOnOptions(options) - args_for_children += ['--no-build', '--build-system=gyp'] - for arg in args: - args_for_children += [arg] - env = os.environ - - for mode in options.mode: - for arch in options.arch: - print ">>> running tests for %s.%s" % (arch, mode) - if options.buildbot: - shellpath = workspace + '/' + options.outdir + '/' + mode - mode = mode.lower() - else: - shellpath = workspace + '/' + options.outdir + '/' + arch + '.' + mode - env['LD_LIBRARY_PATH'] = shellpath + '/lib.target' - shell = shellpath + "/d8" - cmdline = ' '.join(args_for_children + - ['--arch=' + arch] + - ['--mode=' + mode] + - ['--shell=' + shell]) - child = subprocess.Popen(cmdline, - shell=True, - cwd=workspace, - env=env) - returncodes += child.wait() - - if len(options.mode) == 0 and len(options.arch) == 0: - print ">>> running tests" - shellpath = workspace + '/' + options.outdir - env['LD_LIBRARY_PATH'] = shellpath + '/lib.target' - shell = shellpath + '/d8' - child = subprocess.Popen(' '.join(args_for_children + - ['--shell=' + shell]), - shell=True, - cwd=workspace, - env=env) - returncodes = child.wait() - - return returncodes - - -if __name__ == '__main__': - sys.exit(Main()) diff --git a/deps/v8/tools/test.py b/deps/v8/tools/test.py deleted file mode 100755 index c528fc4e20..0000000000 --- a/deps/v8/tools/test.py +++ /dev/null @@ -1,1559 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import imp -import optparse -import os -from os.path import join, dirname, abspath, basename, isdir, exists -import platform -import re -import signal -import subprocess -import sys -import tempfile -import time -import threading -import utils -from Queue import Queue, Empty - - -VERBOSE = False - - -# --------------------------------------------- -# --- P r o g r e s s I n d i c a t o r s --- -# --------------------------------------------- - - -class ProgressIndicator(object): - - def __init__(self, cases): - self.cases = cases - self.queue = Queue(len(cases)) - for case in cases: - self.queue.put_nowait(case) - self.succeeded = 0 - self.remaining = len(cases) - self.total = len(cases) - self.failed = [ ] - self.crashed = 0 - self.terminate = False - self.lock = threading.Lock() - - def PrintFailureHeader(self, test): - if test.IsNegative(): - negative_marker = '[negative] ' - else: - negative_marker = '' - print "=== %(label)s %(negative)s===" % { - 'label': test.GetLabel(), - 'negative': negative_marker - } - print "Path: %s" % "/".join(test.path) - - def Run(self, tasks): - self.Starting() - threads = [] - # Spawn N-1 threads and then use this thread as the last one. - # That way -j1 avoids threading altogether which is a nice fallback - # in case of threading problems. - for i in xrange(tasks - 1): - thread = threading.Thread(target=self.RunSingle, args=[]) - threads.append(thread) - thread.start() - try: - self.RunSingle() - # Wait for the remaining threads - for thread in threads: - # Use a timeout so that signals (ctrl-c) will be processed. - thread.join(timeout=10000000) - except Exception, e: - # If there's an exception we schedule an interruption for any - # remaining threads. - self.terminate = True - # ...and then reraise the exception to bail out - raise - self.Done() - return not self.failed - - def RunSingle(self): - while not self.terminate: - try: - test = self.queue.get_nowait() - except Empty: - return - case = test.case - self.lock.acquire() - self.AboutToRun(case) - self.lock.release() - try: - start = time.time() - output = case.Run() - case.duration = (time.time() - start) - except BreakNowException: - self.terminate = True - except IOError, e: - assert self.terminate - return - if self.terminate: - return - self.lock.acquire() - if output.UnexpectedOutput(): - self.failed.append(output) - if output.HasCrashed(): - self.crashed += 1 - else: - self.succeeded += 1 - self.remaining -= 1 - self.HasRun(output) - self.lock.release() - - -def EscapeCommand(command): - parts = [] - for part in command: - if ' ' in part: - # Escape spaces and double quotes. We may need to escape more characters - # for this to work properly. - parts.append('"%s"' % part.replace('"', '\\"')) - else: - parts.append(part) - return " ".join(parts) - - -class SimpleProgressIndicator(ProgressIndicator): - - def Starting(self): - print 'Running %i tests' % len(self.cases) - - def Done(self): - print - for failed in self.failed: - self.PrintFailureHeader(failed.test) - if failed.output.stderr: - print "--- stderr ---" - print failed.output.stderr.strip() - if failed.output.stdout: - print "--- stdout ---" - print failed.output.stdout.strip() - print "Command: %s" % EscapeCommand(failed.command) - if failed.HasCrashed(): - print "--- CRASHED ---" - if failed.HasTimedOut(): - print "--- TIMEOUT ---" - if len(self.failed) == 0: - print "===" - print "=== All tests succeeded" - print "===" - else: - print - print "===" - print "=== %i tests failed" % len(self.failed) - if self.crashed > 0: - print "=== %i tests CRASHED" % self.crashed - print "===" - - -class VerboseProgressIndicator(SimpleProgressIndicator): - - def AboutToRun(self, case): - print 'Starting %s...' % case.GetLabel() - sys.stdout.flush() - - def HasRun(self, output): - if output.UnexpectedOutput(): - if output.HasCrashed(): - outcome = 'CRASH' - else: - outcome = 'FAIL' - else: - outcome = 'pass' - print 'Done running %s: %s' % (output.test.GetLabel(), outcome) - - -class DotsProgressIndicator(SimpleProgressIndicator): - - def AboutToRun(self, case): - pass - - def HasRun(self, output): - total = self.succeeded + len(self.failed) - if (total > 1) and (total % 50 == 1): - sys.stdout.write('\n') - if output.UnexpectedOutput(): - if output.HasCrashed(): - sys.stdout.write('C') - sys.stdout.flush() - elif output.HasTimedOut(): - sys.stdout.write('T') - sys.stdout.flush() - else: - sys.stdout.write('F') - sys.stdout.flush() - else: - sys.stdout.write('.') - sys.stdout.flush() - - -class CompactProgressIndicator(ProgressIndicator): - - def __init__(self, cases, templates): - super(CompactProgressIndicator, self).__init__(cases) - self.templates = templates - self.last_status_length = 0 - self.start_time = time.time() - - def Starting(self): - pass - - def Done(self): - self.PrintProgress('Done') - - def AboutToRun(self, case): - self.PrintProgress(case.GetLabel()) - - def HasRun(self, output): - if output.UnexpectedOutput(): - self.ClearLine(self.last_status_length) - self.PrintFailureHeader(output.test) - stdout = output.output.stdout.strip() - if len(stdout): - print self.templates['stdout'] % stdout - stderr = output.output.stderr.strip() - if len(stderr): - print self.templates['stderr'] % stderr - print "Command: %s" % EscapeCommand(output.command) - if output.HasCrashed(): - print "--- CRASHED ---" - if output.HasTimedOut(): - print "--- TIMEOUT ---" - - def Truncate(self, str, length): - if length and (len(str) > (length - 3)): - return str[:(length-3)] + "..." - else: - return str - - def PrintProgress(self, name): - self.ClearLine(self.last_status_length) - elapsed = time.time() - self.start_time - status = self.templates['status_line'] % { - 'passed': self.succeeded, - 'remaining': (((self.total - self.remaining) * 100) // self.total), - 'failed': len(self.failed), - 'test': name, - 'mins': int(elapsed) / 60, - 'secs': int(elapsed) % 60 - } - status = self.Truncate(status, 78) - self.last_status_length = len(status) - print status, - sys.stdout.flush() - - -class ColorProgressIndicator(CompactProgressIndicator): - - def __init__(self, cases): - templates = { - 'status_line': "[%(mins)02i:%(secs)02i|\033[34m%%%(remaining) 4d\033[0m|\033[32m+%(passed) 4d\033[0m|\033[31m-%(failed) 4d\033[0m]: %(test)s", - 'stdout': "\033[1m%s\033[0m", - 'stderr': "\033[31m%s\033[0m", - } - super(ColorProgressIndicator, self).__init__(cases, templates) - - def ClearLine(self, last_line_length): - print "\033[1K\r", - - -class MonochromeProgressIndicator(CompactProgressIndicator): - - def __init__(self, cases): - templates = { - 'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s", - 'stdout': '%s', - 'stderr': '%s', - } - super(MonochromeProgressIndicator, self).__init__(cases, templates) - - def ClearLine(self, last_line_length): - print ("\r" + (" " * last_line_length) + "\r"), - - -PROGRESS_INDICATORS = { - 'verbose': VerboseProgressIndicator, - 'dots': DotsProgressIndicator, - 'color': ColorProgressIndicator, - 'mono': MonochromeProgressIndicator -} - - -# ------------------------- -# --- F r a m e w o r k --- -# ------------------------- - -class BreakNowException(Exception): - def __init__(self, value): - self.value = value - def __str__(self): - return repr(self.value) - - -class CommandOutput(object): - - def __init__(self, exit_code, timed_out, stdout, stderr): - self.exit_code = exit_code - self.timed_out = timed_out - self.stdout = stdout - self.stderr = stderr - self.failed = None - - -class TestCase(object): - - def __init__(self, context, path, mode): - self.path = path - self.context = context - self.duration = None - self.mode = mode - - def IsNegative(self): - return False - - def TestsIsolates(self): - return False - - def CompareTime(self, other): - return cmp(other.duration, self.duration) - - def DidFail(self, output): - if output.failed is None: - output.failed = self.IsFailureOutput(output) - return output.failed - - def IsFailureOutput(self, output): - return output.exit_code != 0 - - def GetSource(self): - return "(no source available)" - - def RunCommand(self, command): - full_command = self.context.processor(command) - output = Execute(full_command, - self.context, - self.context.GetTimeout(self, self.mode)) - self.Cleanup() - return TestOutput(self, - full_command, - output, - self.context.store_unexpected_output) - - def BeforeRun(self): - pass - - def AfterRun(self, result): - pass - - def GetCustomFlags(self, mode): - return None - - def Run(self): - self.BeforeRun() - result = None - try: - result = self.RunCommand(self.GetCommand()) - except: - self.terminate = True - raise BreakNowException("User pressed CTRL+C or IO went wrong") - finally: - self.AfterRun(result) - return result - - def Cleanup(self): - return - - -class TestOutput(object): - - def __init__(self, test, command, output, store_unexpected_output): - self.test = test - self.command = command - self.output = output - self.store_unexpected_output = store_unexpected_output - - def UnexpectedOutput(self): - if self.HasCrashed(): - outcome = CRASH - elif self.HasTimedOut(): - outcome = TIMEOUT - elif self.HasFailed(): - outcome = FAIL - else: - outcome = PASS - return not outcome in self.test.outcomes - - def HasPreciousOutput(self): - return self.UnexpectedOutput() and self.store_unexpected_output - - def HasCrashed(self): - if utils.IsWindows(): - return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.output.exit_code) - else: - # Timed out tests will have exit_code -signal.SIGTERM. - if self.output.timed_out: - return False - return self.output.exit_code < 0 and \ - self.output.exit_code != -signal.SIGABRT - - def HasTimedOut(self): - return self.output.timed_out - - def HasFailed(self): - execution_failed = self.test.DidFail(self.output) - if self.test.IsNegative(): - return not execution_failed - else: - return execution_failed - - -def KillProcessWithID(pid): - if utils.IsWindows(): - os.popen('taskkill /T /F /PID %d' % pid) - else: - os.kill(pid, signal.SIGTERM) - - -MAX_SLEEP_TIME = 0.1 -INITIAL_SLEEP_TIME = 0.0001 -SLEEP_TIME_FACTOR = 1.25 - -SEM_INVALID_VALUE = -1 -SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h - -def Win32SetErrorMode(mode): - prev_error_mode = SEM_INVALID_VALUE - try: - import ctypes - prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode) - except ImportError: - pass - return prev_error_mode - -def RunProcess(context, timeout, args, **rest): - if context.verbose: print "#", " ".join(args) - popen_args = args - prev_error_mode = SEM_INVALID_VALUE - if utils.IsWindows(): - popen_args = subprocess.list2cmdline(args) - if context.suppress_dialogs: - # Try to change the error mode to avoid dialogs on fatal errors. Don't - # touch any existing error mode flags by merging the existing error mode. - # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. - error_mode = SEM_NOGPFAULTERRORBOX - prev_error_mode = Win32SetErrorMode(error_mode) - Win32SetErrorMode(error_mode | prev_error_mode) - process = subprocess.Popen( - shell = utils.IsWindows(), - args = popen_args, - **rest - ) - if utils.IsWindows() and context.suppress_dialogs and prev_error_mode != SEM_INVALID_VALUE: - Win32SetErrorMode(prev_error_mode) - # Compute the end time - if the process crosses this limit we - # consider it timed out. - if timeout is None: end_time = None - else: end_time = time.time() + timeout - timed_out = False - # Repeatedly check the exit code from the process in a - # loop and keep track of whether or not it times out. - exit_code = None - sleep_time = INITIAL_SLEEP_TIME - while exit_code is None: - if (not end_time is None) and (time.time() >= end_time): - # Kill the process and wait for it to exit. - KillProcessWithID(process.pid) - exit_code = process.wait() - timed_out = True - else: - exit_code = process.poll() - time.sleep(sleep_time) - sleep_time = sleep_time * SLEEP_TIME_FACTOR - if sleep_time > MAX_SLEEP_TIME: - sleep_time = MAX_SLEEP_TIME - return (process, exit_code, timed_out) - - -def PrintError(str): - sys.stderr.write(str) - sys.stderr.write('\n') - - -def CheckedUnlink(name): - # On Windows, when run with -jN in parallel processes, - # OS often fails to unlink the temp file. Not sure why. - # Need to retry. - # Idea from https://bugs.webkit.org/attachment.cgi?id=75982&action=prettypatch - retry_count = 0 - while retry_count < 30: - try: - os.unlink(name) - return - except OSError, e: - retry_count += 1 - time.sleep(retry_count * 0.1) - PrintError("os.unlink() " + str(e)) - -def Execute(args, context, timeout=None): - (fd_out, outname) = tempfile.mkstemp() - (fd_err, errname) = tempfile.mkstemp() - (process, exit_code, timed_out) = RunProcess( - context, - timeout, - args = args, - stdout = fd_out, - stderr = fd_err, - ) - os.close(fd_out) - os.close(fd_err) - output = file(outname).read() - errors = file(errname).read() - CheckedUnlink(outname) - CheckedUnlink(errname) - return CommandOutput(exit_code, timed_out, output, errors) - - -def ExecuteNoCapture(args, context, timeout=None): - (process, exit_code, timed_out) = RunProcess( - context, - timeout, - args = args, - ) - return CommandOutput(exit_code, False, "", "") - - -def CarCdr(path): - if len(path) == 0: - return (None, [ ]) - else: - return (path[0], path[1:]) - - -# Use this to run several variants of the tests, e.g.: -# VARIANT_FLAGS = [[], ['--always_compact', '--noflush_code']] -VARIANT_FLAGS = [[], - ['--stress-opt', '--always-opt'], - ['--nocrankshaft']] - - -class TestConfiguration(object): - - def __init__(self, context, root): - self.context = context - self.root = root - - def Contains(self, path, file): - if len(path) > len(file): - return False - for i in xrange(len(path)): - if not path[i].match(file[i]): - return False - return True - - def GetTestStatus(self, sections, defs): - pass - - def VariantFlags(self): - return VARIANT_FLAGS - - - - -class TestSuite(object): - - def __init__(self, name): - self.name = name - - def GetName(self): - return self.name - - -class TestRepository(TestSuite): - - def __init__(self, path): - normalized_path = abspath(path) - super(TestRepository, self).__init__(basename(normalized_path)) - self.path = normalized_path - self.is_loaded = False - self.config = None - - def GetConfiguration(self, context): - if self.is_loaded: - return self.config - self.is_loaded = True - file = None - try: - (file, pathname, description) = imp.find_module('testcfg', [ self.path ]) - module = imp.load_module('testcfg', file, pathname, description) - self.config = module.GetConfiguration(context, self.path) - finally: - if file: - file.close() - return self.config - - def GetBuildRequirements(self, path, context): - return self.GetConfiguration(context).GetBuildRequirements() - - def DownloadData(self, context): - config = self.GetConfiguration(context) - if 'DownloadData' in dir(config): - config.DownloadData() - - def AddTestsToList(self, result, current_path, path, context, mode): - config = self.GetConfiguration(context) - for v in config.VariantFlags(): - tests = config.ListTests(current_path, path, mode, v) - for t in tests: t.variant_flags = v - result += tests - - def GetTestStatus(self, context, sections, defs): - self.GetConfiguration(context).GetTestStatus(sections, defs) - - -class LiteralTestSuite(TestSuite): - - def __init__(self, tests): - super(LiteralTestSuite, self).__init__('root') - self.tests = tests - - def GetBuildRequirements(self, path, context): - (name, rest) = CarCdr(path) - result = [ ] - for test in self.tests: - if not name or name.match(test.GetName()): - result += test.GetBuildRequirements(rest, context) - return result - - def DownloadData(self, path, context): - (name, rest) = CarCdr(path) - for test in self.tests: - if not name or name.match(test.GetName()): - test.DownloadData(context) - - def ListTests(self, current_path, path, context, mode, variant_flags): - (name, rest) = CarCdr(path) - result = [ ] - for test in self.tests: - test_name = test.GetName() - if not name or name.match(test_name): - full_path = current_path + [test_name] - test.AddTestsToList(result, full_path, path, context, mode) - return result - - def GetTestStatus(self, context, sections, defs): - for test in self.tests: - test.GetTestStatus(context, sections, defs) - - -SUFFIX = { - 'debug' : '_g', - 'release' : '' } -FLAGS = { - 'debug' : ['--nobreak-on-abort', '--nodead-code-elimination', - '--nofold-constants', '--enable-slow-asserts', - '--debug-code', '--verify-heap'], - 'release' : ['--nobreak-on-abort', '--nodead-code-elimination', - '--nofold-constants']} -TIMEOUT_SCALEFACTOR = { - 'debug' : 4, - 'release' : 1 } - - -class Context(object): - - def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, suppress_dialogs, store_unexpected_output): - self.workspace = workspace - self.buildspace = buildspace - self.verbose = verbose - self.vm_root = vm - self.timeout = timeout - self.processor = processor - self.suppress_dialogs = suppress_dialogs - self.store_unexpected_output = store_unexpected_output - - def GetVm(self, mode): - name = self.vm_root + SUFFIX[mode] - if utils.IsWindows() and not name.endswith('.exe'): - name = name + '.exe' - return name - - def GetVmCommand(self, testcase, mode): - return [self.GetVm(mode)] + self.GetVmFlags(testcase, mode) - - def GetVmFlags(self, testcase, mode): - flags = testcase.GetCustomFlags(mode) - if flags is None: - flags = FLAGS[mode] - return testcase.variant_flags + flags - - def GetTimeout(self, testcase, mode): - result = self.timeout * TIMEOUT_SCALEFACTOR[mode] - if '--stress-opt' in self.GetVmFlags(testcase, mode): - return result * 4 - else: - return result - -def RunTestCases(cases_to_run, progress, tasks): - progress = PROGRESS_INDICATORS[progress](cases_to_run) - result = 0 - try: - result = progress.Run(tasks) - except Exception, e: - print "\n", e - return result - - -def BuildRequirements(context, requirements, mode, scons_flags): - command_line = (['scons', '-Y', context.workspace, 'mode=' + ",".join(mode)] - + requirements - + scons_flags) - output = ExecuteNoCapture(command_line, context) - return output.exit_code == 0 - - -# ------------------------------------------- -# --- T e s t C o n f i g u r a t i o n --- -# ------------------------------------------- - - -SKIP = 'skip' -FAIL = 'fail' -PASS = 'pass' -OKAY = 'okay' -TIMEOUT = 'timeout' -CRASH = 'crash' -SLOW = 'slow' - - -class Expression(object): - pass - - -class Constant(Expression): - - def __init__(self, value): - self.value = value - - def Evaluate(self, env, defs): - return self.value - - -class Variable(Expression): - - def __init__(self, name): - self.name = name - - def GetOutcomes(self, env, defs): - if self.name in env: return ListSet([env[self.name]]) - else: return Nothing() - - def Evaluate(self, env, defs): - return env[self.name] - - -class Outcome(Expression): - - def __init__(self, name): - self.name = name - - def GetOutcomes(self, env, defs): - if self.name in defs: - return defs[self.name].GetOutcomes(env, defs) - else: - return ListSet([self.name]) - - -class Set(object): - pass - - -class ListSet(Set): - - def __init__(self, elms): - self.elms = elms - - def __str__(self): - return "ListSet%s" % str(self.elms) - - def Intersect(self, that): - if not isinstance(that, ListSet): - return that.Intersect(self) - return ListSet([ x for x in self.elms if x in that.elms ]) - - def Union(self, that): - if not isinstance(that, ListSet): - return that.Union(self) - return ListSet(self.elms + [ x for x in that.elms if x not in self.elms ]) - - def IsEmpty(self): - return len(self.elms) == 0 - - -class Everything(Set): - - def Intersect(self, that): - return that - - def Union(self, that): - return self - - def IsEmpty(self): - return False - - -class Nothing(Set): - - def Intersect(self, that): - return self - - def Union(self, that): - return that - - def IsEmpty(self): - return True - - -class Operation(Expression): - - def __init__(self, left, op, right): - self.left = left - self.op = op - self.right = right - - def Evaluate(self, env, defs): - if self.op == '||' or self.op == ',': - return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs) - elif self.op == 'if': - return False - elif self.op == '==': - inter = self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) - return not inter.IsEmpty() - elif self.op == '!=': - inter = self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) - return inter.IsEmpty() - else: - assert self.op == '&&' - return self.left.Evaluate(env, defs) and self.right.Evaluate(env, defs) - - def GetOutcomes(self, env, defs): - if self.op == '||' or self.op == ',': - return self.left.GetOutcomes(env, defs).Union(self.right.GetOutcomes(env, defs)) - elif self.op == 'if': - if self.right.Evaluate(env, defs): return self.left.GetOutcomes(env, defs) - else: return Nothing() - else: - assert self.op == '&&' - return self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) - - -def IsAlpha(str): - for char in str: - if not (char.isalpha() or char.isdigit() or char == '_'): - return False - return True - - -class Tokenizer(object): - """A simple string tokenizer that chops expressions into variables, - parens and operators""" - - def __init__(self, expr): - self.index = 0 - self.expr = expr - self.length = len(expr) - self.tokens = None - - def Current(self, length = 1): - if not self.HasMore(length): return "" - return self.expr[self.index:self.index+length] - - def HasMore(self, length = 1): - return self.index < self.length + (length - 1) - - def Advance(self, count = 1): - self.index = self.index + count - - def AddToken(self, token): - self.tokens.append(token) - - def SkipSpaces(self): - while self.HasMore() and self.Current().isspace(): - self.Advance() - - def Tokenize(self): - self.tokens = [ ] - while self.HasMore(): - self.SkipSpaces() - if not self.HasMore(): - return None - if self.Current() == '(': - self.AddToken('(') - self.Advance() - elif self.Current() == ')': - self.AddToken(')') - self.Advance() - elif self.Current() == '$': - self.AddToken('$') - self.Advance() - elif self.Current() == ',': - self.AddToken(',') - self.Advance() - elif IsAlpha(self.Current()): - buf = "" - while self.HasMore() and IsAlpha(self.Current()): - buf += self.Current() - self.Advance() - self.AddToken(buf) - elif self.Current(2) == '&&': - self.AddToken('&&') - self.Advance(2) - elif self.Current(2) == '||': - self.AddToken('||') - self.Advance(2) - elif self.Current(2) == '==': - self.AddToken('==') - self.Advance(2) - elif self.Current(2) == '!=': - self.AddToken('!=') - self.Advance(2) - else: - return None - return self.tokens - - -class Scanner(object): - """A simple scanner that can serve out tokens from a given list""" - - def __init__(self, tokens): - self.tokens = tokens - self.length = len(tokens) - self.index = 0 - - def HasMore(self): - return self.index < self.length - - def Current(self): - return self.tokens[self.index] - - def Advance(self): - self.index = self.index + 1 - - -def ParseAtomicExpression(scan): - if scan.Current() == "true": - scan.Advance() - return Constant(True) - elif scan.Current() == "false": - scan.Advance() - return Constant(False) - elif IsAlpha(scan.Current()): - name = scan.Current() - scan.Advance() - return Outcome(name.lower()) - elif scan.Current() == '$': - scan.Advance() - if not IsAlpha(scan.Current()): - return None - name = scan.Current() - scan.Advance() - return Variable(name.lower()) - elif scan.Current() == '(': - scan.Advance() - result = ParseLogicalExpression(scan) - if (not result) or (scan.Current() != ')'): - return None - scan.Advance() - return result - else: - return None - - -BINARIES = ['==', '!='] -def ParseOperatorExpression(scan): - left = ParseAtomicExpression(scan) - if not left: return None - while scan.HasMore() and (scan.Current() in BINARIES): - op = scan.Current() - scan.Advance() - right = ParseOperatorExpression(scan) - if not right: - return None - left = Operation(left, op, right) - return left - - -def ParseConditionalExpression(scan): - left = ParseOperatorExpression(scan) - if not left: return None - while scan.HasMore() and (scan.Current() == 'if'): - scan.Advance() - right = ParseOperatorExpression(scan) - if not right: - return None - left = Operation(left, 'if', right) - return left - - -LOGICALS = ["&&", "||", ","] -def ParseLogicalExpression(scan): - left = ParseConditionalExpression(scan) - if not left: return None - while scan.HasMore() and (scan.Current() in LOGICALS): - op = scan.Current() - scan.Advance() - right = ParseConditionalExpression(scan) - if not right: - return None - left = Operation(left, op, right) - return left - - -def ParseCondition(expr): - """Parses a logical expression into an Expression object""" - tokens = Tokenizer(expr).Tokenize() - if not tokens: - print "Malformed expression: '%s'" % expr - return None - scan = Scanner(tokens) - ast = ParseLogicalExpression(scan) - if not ast: - print "Malformed expression: '%s'" % expr - return None - if scan.HasMore(): - print "Malformed expression: '%s'" % expr - return None - return ast - - -class ClassifiedTest(object): - - def __init__(self, case, outcomes): - self.case = case - self.outcomes = outcomes - - def TestsIsolates(self): - return self.case.TestsIsolates() - - -class Configuration(object): - """The parsed contents of a configuration file""" - - def __init__(self, sections, defs): - self.sections = sections - self.defs = defs - - def ClassifyTests(self, cases, env): - sections = [s for s in self.sections if s.condition.Evaluate(env, self.defs)] - all_rules = reduce(list.__add__, [s.rules for s in sections], []) - unused_rules = set(all_rules) - result = [ ] - all_outcomes = set([]) - for case in cases: - matches = [ r for r in all_rules if r.Contains(case.path) ] - outcomes = set([]) - for rule in matches: - outcomes = outcomes.union(rule.GetOutcomes(env, self.defs)) - unused_rules.discard(rule) - if not outcomes: - outcomes = [PASS] - case.outcomes = outcomes - all_outcomes = all_outcomes.union(outcomes) - result.append(ClassifiedTest(case, outcomes)) - return (result, list(unused_rules), all_outcomes) - - -class Section(object): - """A section of the configuration file. Sections are enabled or - disabled prior to running the tests, based on their conditions""" - - def __init__(self, condition): - self.condition = condition - self.rules = [ ] - - def AddRule(self, rule): - self.rules.append(rule) - - -class Rule(object): - """A single rule that specifies the expected outcome for a single - test.""" - - def __init__(self, raw_path, path, value): - self.raw_path = raw_path - self.path = path - self.value = value - - def GetOutcomes(self, env, defs): - set = self.value.GetOutcomes(env, defs) - assert isinstance(set, ListSet) - return set.elms - - def Contains(self, path): - if len(self.path) > len(path): - return False - for i in xrange(len(self.path)): - if not self.path[i].match(path[i]): - return False - return True - - -HEADER_PATTERN = re.compile(r'\[([^]]+)\]') -RULE_PATTERN = re.compile(r'\s*([^: ]*)\s*:(.*)') -DEF_PATTERN = re.compile(r'^def\s*(\w+)\s*=(.*)$') -PREFIX_PATTERN = re.compile(r'^\s*prefix\s+([\w\_\.\-\/]+)$') - - -def ReadConfigurationInto(path, sections, defs): - current_section = Section(Constant(True)) - sections.append(current_section) - prefix = [] - for line in utils.ReadLinesFrom(path): - header_match = HEADER_PATTERN.match(line) - if header_match: - condition_str = header_match.group(1).strip() - condition = ParseCondition(condition_str) - new_section = Section(condition) - sections.append(new_section) - current_section = new_section - continue - rule_match = RULE_PATTERN.match(line) - if rule_match: - path = prefix + SplitPath(rule_match.group(1).strip()) - value_str = rule_match.group(2).strip() - value = ParseCondition(value_str) - if not value: - return False - current_section.AddRule(Rule(rule_match.group(1), path, value)) - continue - def_match = DEF_PATTERN.match(line) - if def_match: - name = def_match.group(1).lower() - value = ParseCondition(def_match.group(2).strip()) - if not value: - return False - defs[name] = value - continue - prefix_match = PREFIX_PATTERN.match(line) - if prefix_match: - prefix = SplitPath(prefix_match.group(1).strip()) - continue - print "Malformed line: '%s'." % line - return False - return True - - -# --------------- -# --- M a i n --- -# --------------- - - -ARCH_GUESS = utils.GuessArchitecture() -TIMEOUT_DEFAULT = 60; - - -def BuildOptions(): - result = optparse.OptionParser() - result.add_option("-m", "--mode", help="The test modes in which to run (comma-separated)", - default='release') - result.add_option("-v", "--verbose", help="Verbose output", - default=False, action="store_true") - result.add_option("-S", dest="scons_flags", help="Flag to pass through to scons", - default=[], action="append") - result.add_option("-p", "--progress", - help="The style of progress indicator (verbose, dots, color, mono)", - choices=PROGRESS_INDICATORS.keys(), default="mono") - result.add_option("--no-build", help="Don't build requirements", - default=False, action="store_true") - result.add_option("--build-only", help="Only build requirements, don't run the tests", - default=False, action="store_true") - result.add_option("--build-system", help="Build system in use (scons or gyp)", - default='scons') - result.add_option("--report", help="Print a summary of the tests to be run", - default=False, action="store_true") - result.add_option("--download-data", help="Download missing test suite data", - default=False, action="store_true") - result.add_option("-s", "--suite", help="A test suite", - default=[], action="append") - result.add_option("-t", "--timeout", help="Timeout in seconds", - default=-1, type="int") - result.add_option("--arch", help='The architecture to run tests for', - default='none') - result.add_option("--snapshot", help="Run the tests with snapshot turned on", - default=False, action="store_true") - result.add_option("--simulator", help="Run tests with architecture simulator", - default='none') - result.add_option("--special-command", default=None) - result.add_option("--valgrind", help="Run tests through valgrind", - default=False, action="store_true") - result.add_option("--cat", help="Print the source of the tests", - default=False, action="store_true") - result.add_option("--warn-unused", help="Report unused rules", - default=False, action="store_true") - result.add_option("-j", help="The number of parallel tasks to run", - default=1, type="int") - result.add_option("--time", help="Print timing information after running", - default=False, action="store_true") - result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for crashing tests", - dest="suppress_dialogs", default=True, action="store_true") - result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for crashing tests", - dest="suppress_dialogs", action="store_false") - result.add_option("--mips-arch-variant", help="mips architecture variant: mips32r1/mips32r2", default="mips32r2"); - result.add_option("--shell", help="Path to V8 shell", default="d8") - result.add_option("--isolates", help="Whether to test isolates", default=False, action="store_true") - result.add_option("--store-unexpected-output", - help="Store the temporary JS files from tests that fails", - dest="store_unexpected_output", default=True, action="store_true") - result.add_option("--no-store-unexpected-output", - help="Deletes the temporary JS files from tests that fails", - dest="store_unexpected_output", action="store_false") - result.add_option("--stress-only", - help="Only run tests with --always-opt --stress-opt", - default=False, action="store_true") - result.add_option("--nostress", - help="Don't run crankshaft --always-opt --stress-op test", - default=False, action="store_true") - result.add_option("--shard-count", - help="Split testsuites into this number of shards", - default=1, type="int") - result.add_option("--shard-run", - help="Run this shard from the split up tests.", - default=1, type="int") - result.add_option("--noprof", help="Disable profiling support", - default=False) - return result - - -def ProcessOptions(options): - global VERBOSE - VERBOSE = options.verbose - options.mode = options.mode.split(',') - for mode in options.mode: - if not mode in ['debug', 'release']: - print "Unknown mode %s" % mode - return False - if options.simulator != 'none': - # Simulator argument was set. Make sure arch and simulator agree. - if options.simulator != options.arch: - if options.arch == 'none': - options.arch = options.simulator - else: - print "Architecture %s does not match sim %s" %(options.arch, options.simulator) - return False - # Ensure that the simulator argument is handed down to scons. - options.scons_flags.append("simulator=" + options.simulator) - else: - # If options.arch is not set by the command line and no simulator setting - # was found, set the arch to the guess. - if options.arch == 'none': - options.arch = ARCH_GUESS - options.scons_flags.append("arch=" + options.arch) - # Simulators are slow, therefore allow a longer default timeout. - if options.timeout == -1: - if options.arch in ['android', 'arm', 'mipsel']: - options.timeout = 2 * TIMEOUT_DEFAULT; - else: - options.timeout = TIMEOUT_DEFAULT; - if options.snapshot: - options.scons_flags.append("snapshot=on") - global VARIANT_FLAGS - if options.mips_arch_variant: - options.scons_flags.append("mips_arch_variant=" + options.mips_arch_variant) - - if options.stress_only: - VARIANT_FLAGS = [['--stress-opt', '--always-opt']] - if options.nostress: - VARIANT_FLAGS = [[],['--nocrankshaft']] - if options.shell.endswith("d8"): - if options.special_command: - options.special_command += " --test" - else: - options.special_command = "@ --test" - if options.noprof: - options.scons_flags.append("prof=off") - options.scons_flags.append("profilingsupport=off") - if options.build_system == 'gyp': - if options.build_only: - print "--build-only not supported for gyp, please build manually." - options.build_only = False - return True - - -def DoSkip(case): - return (SKIP in case.outcomes) or (SLOW in case.outcomes) - - -REPORT_TEMPLATE = """\ -Total: %(total)i tests - * %(skipped)4d tests will be skipped - * %(timeout)4d tests are expected to timeout sometimes - * %(nocrash)4d tests are expected to be flaky but not crash - * %(pass)4d tests are expected to pass - * %(fail_ok)4d tests are expected to fail that we won't fix - * %(fail)4d tests are expected to fail that we should fix\ -""" - -def PrintReport(cases): - def IsFlaky(o): - return (PASS in o) and (FAIL in o) and (not CRASH in o) and (not OKAY in o) - def IsFailOk(o): - return (len(o) == 2) and (FAIL in o) and (OKAY in o) - unskipped = [c for c in cases if not DoSkip(c)] - print REPORT_TEMPLATE % { - 'total': len(cases), - 'skipped': len(cases) - len(unskipped), - 'timeout': len([t for t in unskipped if TIMEOUT in t.outcomes]), - 'nocrash': len([t for t in unskipped if IsFlaky(t.outcomes)]), - 'pass': len([t for t in unskipped if list(t.outcomes) == [PASS]]), - 'fail_ok': len([t for t in unskipped if IsFailOk(t.outcomes)]), - 'fail': len([t for t in unskipped if list(t.outcomes) == [FAIL]]) - } - - -class Pattern(object): - - def __init__(self, pattern): - self.pattern = pattern - self.compiled = None - - def match(self, str): - if not self.compiled: - pattern = "^" + self.pattern.replace('*', '.*') + "$" - self.compiled = re.compile(pattern) - return self.compiled.match(str) - - def __str__(self): - return self.pattern - - -def SplitPath(s): - stripped = [ c.strip() for c in s.split('/') ] - return [ Pattern(s) for s in stripped if len(s) > 0 ] - - -def GetSpecialCommandProcessor(value): - if (not value) or (value.find('@') == -1): - def ExpandCommand(args): - return args - return ExpandCommand - else: - pos = value.find('@') - import urllib - import shlex - prefix = shlex.split(urllib.unquote(value[:pos])) - suffix = shlex.split(urllib.unquote(value[pos+1:])) - def ExpandCommand(args): - return prefix + args + suffix - return ExpandCommand - - -BUILT_IN_TESTS = ['mjsunit', 'cctest', 'message', 'preparser'] - - -def GetSuites(test_root): - def IsSuite(path): - return isdir(path) and exists(join(path, 'testcfg.py')) - return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ] - - -def FormatTime(d): - millis = round(d * 1000) % 1000 - return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) - -def ShardTests(tests, options): - if options.shard_count < 2: - return tests - if options.shard_run < 1 or options.shard_run > options.shard_count: - print "shard-run not a valid number, should be in [1:shard-count]" - print "defaulting back to running all tests" - return tests - count = 0 - shard = [] - for test in tests: - if count % options.shard_count == options.shard_run - 1: - shard.append(test) - count += 1 - return shard - -def Main(): - parser = BuildOptions() - (options, args) = parser.parse_args() - if not ProcessOptions(options): - parser.print_help() - return 1 - - workspace = abspath(join(dirname(sys.argv[0]), '..')) - suites = GetSuites(join(workspace, 'test')) - repositories = [TestRepository(join(workspace, 'test', name)) for name in suites] - repositories += [TestRepository(a) for a in options.suite] - - root = LiteralTestSuite(repositories) - if len(args) == 0: - paths = [SplitPath(t) for t in BUILT_IN_TESTS] - else: - paths = [ ] - for arg in args: - path = SplitPath(arg) - paths.append(path) - - # Check for --valgrind option. If enabled, we overwrite the special - # command flag with a command that uses the run-valgrind.py script. - if options.valgrind: - run_valgrind = join(workspace, "tools", "run-valgrind.py") - options.special_command = "python -u " + run_valgrind + " @" - - if options.build_system == 'gyp': - SUFFIX['debug'] = '' - - shell = abspath(options.shell) - buildspace = dirname(shell) - - context = Context(workspace, buildspace, VERBOSE, - shell, - options.timeout, - GetSpecialCommandProcessor(options.special_command), - options.suppress_dialogs, - options.store_unexpected_output) - # First build the required targets - if not options.no_build: - reqs = [ ] - for path in paths: - reqs += root.GetBuildRequirements(path, context) - reqs = list(set(reqs)) - if len(reqs) > 0: - if options.j != 1: - options.scons_flags += ['-j', str(options.j)] - if not BuildRequirements(context, reqs, options.mode, options.scons_flags): - return 1 - - # Just return if we are only building the targets for running the tests. - if options.build_only: - return 0 - - # Get status for tests - sections = [ ] - defs = { } - root.GetTestStatus(context, sections, defs) - config = Configuration(sections, defs) - - # Download missing test suite data if requested. - if options.download_data: - for path in paths: - root.DownloadData(path, context) - - # List the tests - all_cases = [ ] - all_unused = [ ] - unclassified_tests = [ ] - globally_unused_rules = None - for path in paths: - for mode in options.mode: - env = { - 'mode': mode, - 'system': utils.GuessOS(), - 'arch': options.arch, - 'simulator': options.simulator, - 'isolates': options.isolates - } - test_list = root.ListTests([], path, context, mode, []) - unclassified_tests += test_list - (cases, unused_rules, all_outcomes) = config.ClassifyTests(test_list, env) - if globally_unused_rules is None: - globally_unused_rules = set(unused_rules) - else: - globally_unused_rules = globally_unused_rules.intersection(unused_rules) - all_cases += ShardTests(cases, options) - all_unused.append(unused_rules) - - if options.cat: - visited = set() - for test in unclassified_tests: - key = tuple(test.path) - if key in visited: - continue - visited.add(key) - print "--- begin source: %s ---" % test.GetLabel() - source = test.GetSource().strip() - print source - print "--- end source: %s ---" % test.GetLabel() - return 0 - - if options.warn_unused: - for rule in globally_unused_rules: - print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]) - - if not options.isolates: - all_cases = [c for c in all_cases if not c.TestsIsolates()] - - if options.report: - PrintReport(all_cases) - - result = None - cases_to_run = [ c for c in all_cases if not DoSkip(c) ] - if len(cases_to_run) == 0: - print "No tests to run." - return 0 - else: - try: - start = time.time() - if RunTestCases(cases_to_run, options.progress, options.j): - result = 0 - else: - result = 1 - duration = time.time() - start - except KeyboardInterrupt: - print "Interrupted" - return 1 - - if options.time: - # Write the times to stderr to make it easy to separate from the - # test output. - print - sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration)) - timed_tests = [ t.case for t in cases_to_run if not t.case.duration is None ] - timed_tests.sort(lambda a, b: a.CompareTime(b)) - index = 1 - for entry in timed_tests[:20]: - t = FormatTime(entry.duration) - sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel())) - index += 1 - - return result - - -if __name__ == '__main__': - sys.exit(Main()) |