Created
April 17, 2012 04:09
-
-
Save mashihua/2403390 to your computer and use it in GitHub Desktop.
Patch for v8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Escape the 1.4GB V8 heap limit patch for Version 3.10.2 | |
Usage: patch -p0 < v8.patch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git SConstruct SConstruct | |
index 34d0efc..f5a5627 100644 | |
--- SConstruct | |
+++ SConstruct | |
@@ -1,1604 +1,1605 @@ | |
-# 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'] | |
- }, | |
- 'objectprint:on': { | |
- 'CPPDEFINES': ['OBJECT_PRINT'], | |
- }, | |
- 'debuggersupport:on': { | |
- 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT'], | |
- }, | |
- 'inspector:on': { | |
- 'CPPDEFINES': ['INSPECTOR'], | |
- }, | |
- 'fasttls:off': { | |
- 'CPPDEFINES': ['V8_NO_FAST_TLS'], | |
- }, | |
- 'liveobjectlist:on': { | |
- 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR', | |
- 'LIVE_OBJECT_LIST', 'OBJECT_PRINT'], | |
- } | |
- }, | |
- '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'], | |
- 'LIBS': ['pthread'] | |
- } | |
- }, | |
- 'os:macos': { | |
- 'CCFLAGS': ['-ansi', '-mmacosx-version-min=10.4'], | |
- 'library:shared': { | |
- 'CPPDEFINES': ['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' | |
- }, | |
- 'inspector': { | |
- 'values': ['on', 'off'], | |
- 'default': 'off', | |
- 'help': 'enable inspector features' | |
- }, | |
- 'liveobjectlist': { | |
- 'values': ['on', 'off'], | |
- 'default': 'off', | |
- 'help': 'enable live object list features in the debugger' | |
- }, | |
- '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]' | |
- }, | |
- | |
-} | |
- | |
-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 VerifyOptions(env): | |
- 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' | |
- if options['liveobjectlist'] == 'on': | |
- if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'): | |
- # Print a warning that liveobjectlist will implicitly enable the debugger | |
- print "Warning: forcing debuggersupport on for liveobjectlist" | |
- options['debuggersupport'] = 'on' | |
- options['inspector'] = 'on' | |
- options['objectprint'] = 'on' | |
- | |
- | |
-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() | |
+# 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 #{node_version}OT | |
+# 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], | |
+ 'CPPDEFINES': ['V8_MAX_SEMISPACE_SIZE=536870912'], | |
+ 'regexp:interpreted': { | |
+ 'CPPDEFINES': ['V8_INTERPRETED_REGEXP'] | |
+ }, | |
+ 'mode:debug': { | |
+ 'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT'] | |
+ }, | |
+ 'objectprint:on': { | |
+ 'CPPDEFINES': ['OBJECT_PRINT'], | |
+ }, | |
+ 'debuggersupport:on': { | |
+ 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT'], | |
+ }, | |
+ 'inspector:on': { | |
+ 'CPPDEFINES': ['INSPECTOR'], | |
+ }, | |
+ 'fasttls:off': { | |
+ 'CPPDEFINES': ['V8_NO_FAST_TLS'], | |
+ }, | |
+ 'liveobjectlist:on': { | |
+ 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR', | |
+ 'LIVE_OBJECT_LIST', 'OBJECT_PRINT'], | |
+ } | |
+ }, | |
+ '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'], | |
+ 'LIBS': ['pthread'] | |
+ } | |
+ }, | |
+ 'os:macos': { | |
+ 'CCFLAGS': ['-ansi', '-mmacosx-version-min=10.4'], | |
+ 'library:shared': { | |
+ 'CPPDEFINES': ['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' | |
+ }, | |
+ 'inspector': { | |
+ 'values': ['on', 'off'], | |
+ 'default': 'off', | |
+ 'help': 'enable inspector features' | |
+ }, | |
+ 'liveobjectlist': { | |
+ 'values': ['on', 'off'], | |
+ 'default': 'off', | |
+ 'help': 'enable live object list features in the debugger' | |
+ }, | |
+ '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]' | |
+ }, | |
+ | |
+} | |
+ | |
+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 VerifyOptions(env): | |
+ 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' | |
+ if options['liveobjectlist'] == 'on': | |
+ if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'): | |
+ # Print a warning that liveobjectlist will implicitly enable the debugger | |
+ print "Warning: forcing debuggersupport on for liveobjectlist" | |
+ options['debuggersupport'] = 'on' | |
+ options['inspector'] = 'on' | |
+ options['objectprint'] = 'on' | |
+ | |
+ | |
+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 src/heap-inl.h src/heap-inl.h | |
index e12895a..55ce0ca 100644 | |
--- src/heap-inl.h | |
+++ src/heap-inl.h | |
@@ -1,793 +1,793 @@ | |
-// 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. | |
- | |
-#ifndef V8_HEAP_INL_H_ | |
-#define V8_HEAP_INL_H_ | |
- | |
-#include "heap.h" | |
-#include "isolate.h" | |
-#include "list-inl.h" | |
-#include "objects.h" | |
-#include "platform.h" | |
-#include "v8-counters.h" | |
-#include "store-buffer.h" | |
-#include "store-buffer-inl.h" | |
- | |
-namespace v8 { | |
-namespace internal { | |
- | |
-void PromotionQueue::insert(HeapObject* target, int size) { | |
- if (emergency_stack_ != NULL) { | |
- emergency_stack_->Add(Entry(target, size)); | |
- return; | |
- } | |
- | |
- if (NewSpacePage::IsAtStart(reinterpret_cast<Address>(rear_))) { | |
- NewSpacePage* rear_page = | |
- NewSpacePage::FromAddress(reinterpret_cast<Address>(rear_)); | |
- ASSERT(!rear_page->prev_page()->is_anchor()); | |
- rear_ = reinterpret_cast<intptr_t*>(rear_page->prev_page()->area_end()); | |
- ActivateGuardIfOnTheSamePage(); | |
- } | |
- | |
- if (guard_) { | |
- ASSERT(GetHeadPage() == | |
- Page::FromAllocationTop(reinterpret_cast<Address>(limit_))); | |
- | |
- if ((rear_ - 2) < limit_) { | |
- RelocateQueueHead(); | |
- emergency_stack_->Add(Entry(target, size)); | |
- return; | |
- } | |
- } | |
- | |
- *(--rear_) = reinterpret_cast<intptr_t>(target); | |
- *(--rear_) = size; | |
- // Assert no overflow into live objects. | |
-#ifdef DEBUG | |
- SemiSpace::AssertValidRange(HEAP->new_space()->top(), | |
- reinterpret_cast<Address>(rear_)); | |
-#endif | |
-} | |
- | |
- | |
-void PromotionQueue::ActivateGuardIfOnTheSamePage() { | |
- guard_ = guard_ || | |
- heap_->new_space()->active_space()->current_page()->address() == | |
- GetHeadPage()->address(); | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str, | |
- PretenureFlag pretenure) { | |
- // Check for ASCII first since this is the common case. | |
- if (String::IsAscii(str.start(), str.length())) { | |
- // If the string is ASCII, we do not need to convert the characters | |
- // since UTF8 is backwards compatible with ASCII. | |
- return AllocateStringFromAscii(str, pretenure); | |
- } | |
- // Non-ASCII and we need to decode. | |
- return AllocateStringFromUtf8Slow(str, pretenure); | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateSymbol(Vector<const char> str, | |
- int chars, | |
- uint32_t hash_field) { | |
- unibrow::Utf8InputBuffer<> buffer(str.start(), | |
- static_cast<unsigned>(str.length())); | |
- return AllocateInternalSymbol(&buffer, chars, hash_field); | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str, | |
- uint32_t hash_field) { | |
- if (str.length() > SeqAsciiString::kMaxLength) { | |
- return Failure::OutOfMemoryException(); | |
- } | |
- // Compute map and object size. | |
- Map* map = ascii_symbol_map(); | |
- int size = SeqAsciiString::SizeFor(str.length()); | |
- | |
- // Allocate string. | |
- Object* result; | |
- { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) | |
- ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | |
- : old_data_space_->AllocateRaw(size); | |
- if (!maybe_result->ToObject(&result)) return maybe_result; | |
- } | |
- | |
- // String maps are all immortal immovable objects. | |
- reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map); | |
- // Set length and hash fields of the allocated string. | |
- String* answer = String::cast(result); | |
- answer->set_length(str.length()); | |
- answer->set_hash_field(hash_field); | |
- | |
- ASSERT_EQ(size, answer->Size()); | |
- | |
- // Fill in the characters. | |
- memcpy(answer->address() + SeqAsciiString::kHeaderSize, | |
- str.start(), str.length()); | |
- | |
- return answer; | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str, | |
- uint32_t hash_field) { | |
- if (str.length() > SeqTwoByteString::kMaxLength) { | |
- return Failure::OutOfMemoryException(); | |
- } | |
- // Compute map and object size. | |
- Map* map = symbol_map(); | |
- int size = SeqTwoByteString::SizeFor(str.length()); | |
- | |
- // Allocate string. | |
- Object* result; | |
- { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) | |
- ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | |
- : old_data_space_->AllocateRaw(size); | |
- if (!maybe_result->ToObject(&result)) return maybe_result; | |
- } | |
- | |
- reinterpret_cast<HeapObject*>(result)->set_map(map); | |
- // Set length and hash fields of the allocated string. | |
- String* answer = String::cast(result); | |
- answer->set_length(str.length()); | |
- answer->set_hash_field(hash_field); | |
- | |
- ASSERT_EQ(size, answer->Size()); | |
- | |
- // Fill in the characters. | |
- memcpy(answer->address() + SeqTwoByteString::kHeaderSize, | |
- str.start(), str.length() * kUC16Size); | |
- | |
- return answer; | |
-} | |
- | |
-MaybeObject* Heap::CopyFixedArray(FixedArray* src) { | |
- return CopyFixedArrayWithMap(src, src->map()); | |
-} | |
- | |
- | |
-MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) { | |
- return CopyFixedDoubleArrayWithMap(src, src->map()); | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateRaw(int size_in_bytes, | |
- AllocationSpace space, | |
- AllocationSpace retry_space) { | |
- ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | |
- ASSERT(space != NEW_SPACE || | |
- retry_space == OLD_POINTER_SPACE || | |
- retry_space == OLD_DATA_SPACE || | |
- retry_space == LO_SPACE); | |
-#ifdef DEBUG | |
- if (FLAG_gc_interval >= 0 && | |
- !disallow_allocation_failure_ && | |
- Heap::allocation_timeout_-- <= 0) { | |
- return Failure::RetryAfterGC(space); | |
- } | |
- isolate_->counters()->objs_since_last_full()->Increment(); | |
- isolate_->counters()->objs_since_last_young()->Increment(); | |
-#endif | |
- MaybeObject* result; | |
- if (NEW_SPACE == space) { | |
- result = new_space_.AllocateRaw(size_in_bytes); | |
- if (always_allocate() && result->IsFailure()) { | |
- space = retry_space; | |
- } else { | |
- return result; | |
- } | |
- } | |
- | |
- if (OLD_POINTER_SPACE == space) { | |
- result = old_pointer_space_->AllocateRaw(size_in_bytes); | |
- } else if (OLD_DATA_SPACE == space) { | |
- result = old_data_space_->AllocateRaw(size_in_bytes); | |
- } else if (CODE_SPACE == space) { | |
- result = code_space_->AllocateRaw(size_in_bytes); | |
- } else if (LO_SPACE == space) { | |
- result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE); | |
- } else if (CELL_SPACE == space) { | |
- result = cell_space_->AllocateRaw(size_in_bytes); | |
- } else { | |
- ASSERT(MAP_SPACE == space); | |
- result = map_space_->AllocateRaw(size_in_bytes); | |
- } | |
- if (result->IsFailure()) old_gen_exhausted_ = true; | |
- return result; | |
-} | |
- | |
- | |
-MaybeObject* Heap::NumberFromInt32( | |
- int32_t value, PretenureFlag pretenure) { | |
- if (Smi::IsValid(value)) return Smi::FromInt(value); | |
- // Bypass NumberFromDouble to avoid various redundant checks. | |
- return AllocateHeapNumber(FastI2D(value), pretenure); | |
-} | |
- | |
- | |
-MaybeObject* Heap::NumberFromUint32( | |
- uint32_t value, PretenureFlag pretenure) { | |
- if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) { | |
- return Smi::FromInt((int32_t)value); | |
- } | |
- // Bypass NumberFromDouble to avoid various redundant checks. | |
- return AllocateHeapNumber(FastUI2D(value), pretenure); | |
-} | |
- | |
- | |
-void Heap::FinalizeExternalString(String* string) { | |
- ASSERT(string->IsExternalString()); | |
- v8::String::ExternalStringResourceBase** resource_addr = | |
- reinterpret_cast<v8::String::ExternalStringResourceBase**>( | |
- reinterpret_cast<byte*>(string) + | |
- ExternalString::kResourceOffset - | |
- kHeapObjectTag); | |
- | |
- // Dispose of the C++ object if it has not already been disposed. | |
- if (*resource_addr != NULL) { | |
- (*resource_addr)->Dispose(); | |
- *resource_addr = NULL; | |
- } | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateRawMap() { | |
-#ifdef DEBUG | |
- isolate_->counters()->objs_since_last_full()->Increment(); | |
- isolate_->counters()->objs_since_last_young()->Increment(); | |
-#endif | |
- MaybeObject* result = map_space_->AllocateRaw(Map::kSize); | |
- if (result->IsFailure()) old_gen_exhausted_ = true; | |
-#ifdef DEBUG | |
- if (!result->IsFailure()) { | |
- // Maps have their own alignment. | |
- CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) == | |
- static_cast<intptr_t>(kHeapObjectTag)); | |
- } | |
-#endif | |
- return result; | |
-} | |
- | |
- | |
-MaybeObject* Heap::AllocateRawCell() { | |
-#ifdef DEBUG | |
- isolate_->counters()->objs_since_last_full()->Increment(); | |
- isolate_->counters()->objs_since_last_young()->Increment(); | |
-#endif | |
- MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize); | |
- if (result->IsFailure()) old_gen_exhausted_ = true; | |
- return result; | |
-} | |
- | |
- | |
-bool Heap::InNewSpace(Object* object) { | |
- bool result = new_space_.Contains(object); | |
- ASSERT(!result || // Either not in new space | |
- gc_state_ != NOT_IN_GC || // ... or in the middle of GC | |
- InToSpace(object)); // ... or in to-space (where we allocate). | |
- return result; | |
-} | |
- | |
- | |
-bool Heap::InNewSpace(Address addr) { | |
- return new_space_.Contains(addr); | |
-} | |
- | |
- | |
-bool Heap::InFromSpace(Object* object) { | |
- return new_space_.FromSpaceContains(object); | |
-} | |
- | |
- | |
-bool Heap::InToSpace(Object* object) { | |
- return new_space_.ToSpaceContains(object); | |
-} | |
- | |
- | |
-bool Heap::OldGenerationAllocationLimitReached() { | |
- if (!incremental_marking()->IsStopped()) return false; | |
- return OldGenerationSpaceAvailable() < 0; | |
-} | |
- | |
- | |
-bool Heap::ShouldBePromoted(Address old_address, int object_size) { | |
- // An object should be promoted if: | |
- // - the object has survived a scavenge operation or | |
- // - to space is already 25% full. | |
- NewSpacePage* page = NewSpacePage::FromAddress(old_address); | |
- Address age_mark = new_space_.age_mark(); | |
- bool below_mark = page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) && | |
- (!page->ContainsLimit(age_mark) || old_address < age_mark); | |
- return below_mark || (new_space_.Size() + object_size) >= | |
- (new_space_.EffectiveCapacity() >> 2); | |
-} | |
- | |
- | |
-void Heap::RecordWrite(Address address, int offset) { | |
- if (!InNewSpace(address)) store_buffer_.Mark(address + offset); | |
-} | |
- | |
- | |
-void Heap::RecordWrites(Address address, int start, int len) { | |
- if (!InNewSpace(address)) { | |
- for (int i = 0; i < len; i++) { | |
- store_buffer_.Mark(address + start + i * kPointerSize); | |
- } | |
- } | |
-} | |
- | |
- | |
-OldSpace* Heap::TargetSpace(HeapObject* object) { | |
- InstanceType type = object->map()->instance_type(); | |
- AllocationSpace space = TargetSpaceId(type); | |
- return (space == OLD_POINTER_SPACE) | |
- ? old_pointer_space_ | |
- : old_data_space_; | |
-} | |
- | |
- | |
-AllocationSpace Heap::TargetSpaceId(InstanceType type) { | |
- // Heap numbers and sequential strings are promoted to old data space, all | |
- // other object types are promoted to old pointer space. We do not use | |
- // object->IsHeapNumber() and object->IsSeqString() because we already | |
- // know that object has the heap object tag. | |
- | |
- // These objects are never allocated in new space. | |
- ASSERT(type != MAP_TYPE); | |
- ASSERT(type != CODE_TYPE); | |
- ASSERT(type != ODDBALL_TYPE); | |
- ASSERT(type != JS_GLOBAL_PROPERTY_CELL_TYPE); | |
- | |
- if (type < FIRST_NONSTRING_TYPE) { | |
- // There are four string representations: sequential strings, external | |
- // strings, cons strings, and sliced strings. | |
- // Only the latter two contain non-map-word pointers to heap objects. | |
- return ((type & kIsIndirectStringMask) == kIsIndirectStringTag) | |
- ? OLD_POINTER_SPACE | |
- : OLD_DATA_SPACE; | |
- } else { | |
- return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE; | |
- } | |
-} | |
- | |
- | |
-void Heap::CopyBlock(Address dst, Address src, int byte_size) { | |
- CopyWords(reinterpret_cast<Object**>(dst), | |
- reinterpret_cast<Object**>(src), | |
- byte_size / kPointerSize); | |
-} | |
- | |
- | |
-void Heap::MoveBlock(Address dst, Address src, int byte_size) { | |
- ASSERT(IsAligned(byte_size, kPointerSize)); | |
- | |
- int size_in_words = byte_size / kPointerSize; | |
- | |
- if ((dst < src) || (dst >= (src + byte_size))) { | |
- Object** src_slot = reinterpret_cast<Object**>(src); | |
- Object** dst_slot = reinterpret_cast<Object**>(dst); | |
- Object** end_slot = src_slot + size_in_words; | |
- | |
- while (src_slot != end_slot) { | |
- *dst_slot++ = *src_slot++; | |
- } | |
- } else { | |
- memmove(dst, src, byte_size); | |
- } | |
-} | |
- | |
- | |
-void Heap::ScavengePointer(HeapObject** p) { | |
- ScavengeObject(p, *p); | |
-} | |
- | |
- | |
-void Heap::ScavengeObject(HeapObject** p, HeapObject* object) { | |
- ASSERT(HEAP->InFromSpace(object)); | |
- | |
- // We use the first word (where the map pointer usually is) of a heap | |
- // object to record the forwarding pointer. A forwarding pointer can | |
- // point to an old space, the code space, or the to space of the new | |
- // generation. | |
- MapWord first_word = object->map_word(); | |
- | |
- // If the first word is a forwarding address, the object has already been | |
- // copied. | |
- if (first_word.IsForwardingAddress()) { | |
- HeapObject* dest = first_word.ToForwardingAddress(); | |
- ASSERT(HEAP->InFromSpace(*p)); | |
- *p = dest; | |
- return; | |
- } | |
- | |
- // Call the slow part of scavenge object. | |
- return ScavengeObjectSlow(p, object); | |
-} | |
- | |
- | |
-bool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason) { | |
- const char* collector_reason = NULL; | |
- GarbageCollector collector = SelectGarbageCollector(space, &collector_reason); | |
- return CollectGarbage(space, collector, gc_reason, collector_reason); | |
-} | |
- | |
- | |
-MaybeObject* Heap::PrepareForCompare(String* str) { | |
- // Always flatten small strings and force flattening of long strings | |
- // after we have accumulated a certain amount we failed to flatten. | |
- static const int kMaxAlwaysFlattenLength = 32; | |
- static const int kFlattenLongThreshold = 16*KB; | |
- | |
- const int length = str->length(); | |
- MaybeObject* obj = str->TryFlatten(); | |
- if (length <= kMaxAlwaysFlattenLength || | |
- unflattened_strings_length_ >= kFlattenLongThreshold) { | |
- return obj; | |
- } | |
- if (obj->IsFailure()) { | |
- unflattened_strings_length_ += length; | |
- } | |
- return str; | |
-} | |
- | |
- | |
-intptr_t Heap::AdjustAmountOfExternalAllocatedMemory( | |
- intptr_t change_in_bytes) { | |
- ASSERT(HasBeenSetUp()); | |
- intptr_t amount = amount_of_external_allocated_memory_ + change_in_bytes; | |
- if (change_in_bytes >= 0) { | |
- // Avoid overflow. | |
- if (amount > amount_of_external_allocated_memory_) { | |
- amount_of_external_allocated_memory_ = amount; | |
- } | |
- intptr_t amount_since_last_global_gc = | |
- amount_of_external_allocated_memory_ - | |
- amount_of_external_allocated_memory_at_last_global_gc_; | |
- if (amount_since_last_global_gc > external_allocation_limit_) { | |
- CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached"); | |
- } | |
- } else { | |
- // Avoid underflow. | |
- if (amount >= 0) { | |
- amount_of_external_allocated_memory_ = amount; | |
- } | |
- } | |
- ASSERT(amount_of_external_allocated_memory_ >= 0); | |
- return amount_of_external_allocated_memory_; | |
-} | |
- | |
- | |
-void Heap::SetLastScriptId(Object* last_script_id) { | |
- roots_[kLastScriptIdRootIndex] = last_script_id; | |
-} | |
- | |
- | |
-Isolate* Heap::isolate() { | |
- return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) - | |
- reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4); | |
-} | |
- | |
- | |
-#ifdef DEBUG | |
-#define GC_GREEDY_CHECK() \ | |
- if (FLAG_gc_greedy) HEAP->GarbageCollectionGreedyCheck() | |
-#else | |
-#define GC_GREEDY_CHECK() { } | |
-#endif | |
- | |
-// Calls the FUNCTION_CALL function and retries it up to three times | |
-// to guarantee that any allocations performed during the call will | |
-// succeed if there's enough memory. | |
- | |
-// Warning: Do not use the identifiers __object__, __maybe_object__ or | |
-// __scope__ in a call to this macro. | |
- | |
-#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)\ | |
- do { \ | |
- GC_GREEDY_CHECK(); \ | |
- MaybeObject* __maybe_object__ = FUNCTION_CALL; \ | |
- Object* __object__ = NULL; \ | |
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
- if (__maybe_object__->IsOutOfMemory()) { \ | |
- v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\ | |
- } \ | |
- if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ | |
- ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ | |
- allocation_space(), \ | |
- "allocation failure"); \ | |
- __maybe_object__ = FUNCTION_CALL; \ | |
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
- if (__maybe_object__->IsOutOfMemory()) { \ | |
- v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\ | |
- } \ | |
- if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ | |
- ISOLATE->counters()->gc_last_resort_from_handles()->Increment(); \ | |
- ISOLATE->heap()->CollectAllAvailableGarbage("last resort gc"); \ | |
- { \ | |
- AlwaysAllocateScope __scope__; \ | |
- __maybe_object__ = FUNCTION_CALL; \ | |
- } \ | |
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
- if (__maybe_object__->IsOutOfMemory() || \ | |
- __maybe_object__->IsRetryAfterGC()) { \ | |
- /* TODO(1181417): Fix this. */ \ | |
- v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\ | |
- } \ | |
- RETURN_EMPTY; \ | |
- } while (false) | |
- | |
- | |
-#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ | |
- CALL_AND_RETRY(ISOLATE, \ | |
- FUNCTION_CALL, \ | |
- return Handle<TYPE>(TYPE::cast(__object__), ISOLATE), \ | |
- return Handle<TYPE>()) | |
- | |
- | |
-#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ | |
- CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) | |
- | |
- | |
-#ifdef DEBUG | |
- | |
-inline bool Heap::allow_allocation(bool new_state) { | |
- bool old = allocation_allowed_; | |
- allocation_allowed_ = new_state; | |
- return old; | |
-} | |
- | |
-#endif | |
- | |
- | |
-void ExternalStringTable::AddString(String* string) { | |
- ASSERT(string->IsExternalString()); | |
- if (heap_->InNewSpace(string)) { | |
- new_space_strings_.Add(string); | |
- } else { | |
- old_space_strings_.Add(string); | |
- } | |
-} | |
- | |
- | |
-void ExternalStringTable::Iterate(ObjectVisitor* v) { | |
- if (!new_space_strings_.is_empty()) { | |
- Object** start = &new_space_strings_[0]; | |
- v->VisitPointers(start, start + new_space_strings_.length()); | |
- } | |
- if (!old_space_strings_.is_empty()) { | |
- Object** start = &old_space_strings_[0]; | |
- v->VisitPointers(start, start + old_space_strings_.length()); | |
- } | |
-} | |
- | |
- | |
-// Verify() is inline to avoid ifdef-s around its calls in release | |
-// mode. | |
-void ExternalStringTable::Verify() { | |
-#ifdef DEBUG | |
- for (int i = 0; i < new_space_strings_.length(); ++i) { | |
- ASSERT(heap_->InNewSpace(new_space_strings_[i])); | |
- ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_the_hole_value()); | |
- } | |
- for (int i = 0; i < old_space_strings_.length(); ++i) { | |
- ASSERT(!heap_->InNewSpace(old_space_strings_[i])); | |
- ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_the_hole_value()); | |
- } | |
-#endif | |
-} | |
- | |
- | |
-void ExternalStringTable::AddOldString(String* string) { | |
- ASSERT(string->IsExternalString()); | |
- ASSERT(!heap_->InNewSpace(string)); | |
- old_space_strings_.Add(string); | |
-} | |
- | |
- | |
-void ExternalStringTable::ShrinkNewStrings(int position) { | |
- new_space_strings_.Rewind(position); | |
- if (FLAG_verify_heap) { | |
- Verify(); | |
- } | |
-} | |
- | |
- | |
-void Heap::ClearInstanceofCache() { | |
- set_instanceof_cache_function(the_hole_value()); | |
-} | |
- | |
- | |
-Object* Heap::ToBoolean(bool condition) { | |
- return condition ? true_value() : false_value(); | |
-} | |
- | |
- | |
-void Heap::CompletelyClearInstanceofCache() { | |
- set_instanceof_cache_map(the_hole_value()); | |
- set_instanceof_cache_function(the_hole_value()); | |
-} | |
- | |
- | |
-MaybeObject* TranscendentalCache::Get(Type type, double input) { | |
- SubCache* cache = caches_[type]; | |
- if (cache == NULL) { | |
- caches_[type] = cache = new SubCache(type); | |
- } | |
- return cache->Get(input); | |
-} | |
- | |
- | |
-Address TranscendentalCache::cache_array_address() { | |
- return reinterpret_cast<Address>(caches_); | |
-} | |
- | |
- | |
-double TranscendentalCache::SubCache::Calculate(double input) { | |
- switch (type_) { | |
- case ACOS: | |
- return acos(input); | |
- case ASIN: | |
- return asin(input); | |
- case ATAN: | |
- return atan(input); | |
- case COS: | |
- return fast_cos(input); | |
- case EXP: | |
- return exp(input); | |
- case LOG: | |
- return fast_log(input); | |
- case SIN: | |
- return fast_sin(input); | |
- case TAN: | |
- return fast_tan(input); | |
- default: | |
- return 0.0; // Never happens. | |
- } | |
-} | |
- | |
- | |
-MaybeObject* TranscendentalCache::SubCache::Get(double input) { | |
- Converter c; | |
- c.dbl = input; | |
- int hash = Hash(c); | |
- Element e = elements_[hash]; | |
- if (e.in[0] == c.integers[0] && | |
- e.in[1] == c.integers[1]) { | |
- ASSERT(e.output != NULL); | |
- isolate_->counters()->transcendental_cache_hit()->Increment(); | |
- return e.output; | |
- } | |
- double answer = Calculate(input); | |
- isolate_->counters()->transcendental_cache_miss()->Increment(); | |
- Object* heap_number; | |
- { MaybeObject* maybe_heap_number = | |
- isolate_->heap()->AllocateHeapNumber(answer); | |
- if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number; | |
- } | |
- elements_[hash].in[0] = c.integers[0]; | |
- elements_[hash].in[1] = c.integers[1]; | |
- elements_[hash].output = heap_number; | |
- return heap_number; | |
-} | |
- | |
- | |
-AlwaysAllocateScope::AlwaysAllocateScope() { | |
- // We shouldn't hit any nested scopes, because that requires | |
- // non-handle code to call handle code. The code still works but | |
- // performance will degrade, so we want to catch this situation | |
- // in debug mode. | |
- ASSERT(HEAP->always_allocate_scope_depth_ == 0); | |
- HEAP->always_allocate_scope_depth_++; | |
-} | |
- | |
- | |
-AlwaysAllocateScope::~AlwaysAllocateScope() { | |
- HEAP->always_allocate_scope_depth_--; | |
- ASSERT(HEAP->always_allocate_scope_depth_ == 0); | |
-} | |
- | |
- | |
-LinearAllocationScope::LinearAllocationScope() { | |
- HEAP->linear_allocation_scope_depth_++; | |
-} | |
- | |
- | |
-LinearAllocationScope::~LinearAllocationScope() { | |
- HEAP->linear_allocation_scope_depth_--; | |
- ASSERT(HEAP->linear_allocation_scope_depth_ >= 0); | |
-} | |
- | |
- | |
-#ifdef DEBUG | |
-void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) { | |
- for (Object** current = start; current < end; current++) { | |
- if ((*current)->IsHeapObject()) { | |
- HeapObject* object = HeapObject::cast(*current); | |
- ASSERT(HEAP->Contains(object)); | |
- ASSERT(object->map()->IsMap()); | |
- } | |
- } | |
-} | |
-#endif | |
- | |
- | |
-double GCTracer::SizeOfHeapObjects() { | |
- return (static_cast<double>(HEAP->SizeOfObjects())) / MB; | |
-} | |
- | |
- | |
-#ifdef DEBUG | |
-DisallowAllocationFailure::DisallowAllocationFailure() { | |
- old_state_ = HEAP->disallow_allocation_failure_; | |
- HEAP->disallow_allocation_failure_ = true; | |
-} | |
- | |
- | |
-DisallowAllocationFailure::~DisallowAllocationFailure() { | |
- HEAP->disallow_allocation_failure_ = old_state_; | |
-} | |
-#endif | |
- | |
- | |
-#ifdef DEBUG | |
-AssertNoAllocation::AssertNoAllocation() { | |
- old_state_ = HEAP->allow_allocation(false); | |
-} | |
- | |
- | |
-AssertNoAllocation::~AssertNoAllocation() { | |
- HEAP->allow_allocation(old_state_); | |
-} | |
- | |
- | |
-DisableAssertNoAllocation::DisableAssertNoAllocation() { | |
- old_state_ = HEAP->allow_allocation(true); | |
-} | |
- | |
- | |
-DisableAssertNoAllocation::~DisableAssertNoAllocation() { | |
- HEAP->allow_allocation(old_state_); | |
-} | |
- | |
-#else | |
- | |
-AssertNoAllocation::AssertNoAllocation() { } | |
-AssertNoAllocation::~AssertNoAllocation() { } | |
-DisableAssertNoAllocation::DisableAssertNoAllocation() { } | |
-DisableAssertNoAllocation::~DisableAssertNoAllocation() { } | |
- | |
-#endif | |
- | |
- | |
-} } // namespace v8::internal | |
- | |
-#endif // V8_HEAP_INL_H_ | |
+// 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. | |
+ | |
+#ifndef V8_HEAP_INL_H_ | |
+#define V8_HEAP_INL_H_ | |
+ | |
+#include "heap.h" | |
+#include "isolate.h" | |
+#include "list-inl.h" | |
+#include "objects.h" | |
+#include "platform.h" | |
+#include "v8-counters.h" | |
+#include "store-buffer.h" | |
+#include "store-buffer-inl.h" | |
+ | |
+namespace v8 { | |
+namespace internal { | |
+ | |
+void PromotionQueue::insert(HeapObject* target, int size) { | |
+ if (emergency_stack_ != NULL) { | |
+ emergency_stack_->Add(Entry(target, size)); | |
+ return; | |
+ } | |
+ | |
+ if (NewSpacePage::IsAtStart(reinterpret_cast<Address>(rear_))) { | |
+ NewSpacePage* rear_page = | |
+ NewSpacePage::FromAddress(reinterpret_cast<Address>(rear_)); | |
+ ASSERT(!rear_page->prev_page()->is_anchor()); | |
+ rear_ = reinterpret_cast<intptr_t*>(rear_page->prev_page()->area_end()); | |
+ ActivateGuardIfOnTheSamePage(); | |
+ } | |
+ | |
+ if (guard_) { | |
+ ASSERT(GetHeadPage() == | |
+ Page::FromAllocationTop(reinterpret_cast<Address>(limit_))); | |
+ | |
+ if ((rear_ - 2) < limit_) { | |
+ RelocateQueueHead(); | |
+ emergency_stack_->Add(Entry(target, size)); | |
+ return; | |
+ } | |
+ } | |
+ | |
+ *(--rear_) = reinterpret_cast<intptr_t>(target); | |
+ *(--rear_) = size; | |
+ // Assert no overflow into live objects. | |
+#ifdef DEBUG | |
+ SemiSpace::AssertValidRange(HEAP->new_space()->top(), | |
+ reinterpret_cast<Address>(rear_)); | |
+#endif | |
+} | |
+ | |
+ | |
+void PromotionQueue::ActivateGuardIfOnTheSamePage() { | |
+ guard_ = guard_ || | |
+ heap_->new_space()->active_space()->current_page()->address() == | |
+ GetHeadPage()->address(); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str, | |
+ PretenureFlag pretenure) { | |
+ // Check for ASCII first since this is the common case. | |
+ if (String::IsAscii(str.start(), str.length())) { | |
+ // If the string is ASCII, we do not need to convert the characters | |
+ // since UTF8 is backwards compatible with ASCII. | |
+ return AllocateStringFromAscii(str, pretenure); | |
+ } | |
+ // Non-ASCII and we need to decode. | |
+ return AllocateStringFromUtf8Slow(str, pretenure); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateSymbol(Vector<const char> str, | |
+ int chars, | |
+ uint32_t hash_field) { | |
+ unibrow::Utf8InputBuffer<> buffer(str.start(), | |
+ static_cast<unsigned>(str.length())); | |
+ return AllocateInternalSymbol(&buffer, chars, hash_field); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str, | |
+ uint32_t hash_field) { | |
+ if (str.length() > SeqAsciiString::kMaxLength) { | |
+ return Failure::OutOfMemoryException(); | |
+ } | |
+ // Compute map and object size. | |
+ Map* map = ascii_symbol_map(); | |
+ int size = SeqAsciiString::SizeFor(str.length()); | |
+ | |
+ // Allocate string. | |
+ Object* result; | |
+ { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) | |
+ ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | |
+ : old_data_space_->AllocateRaw(size); | |
+ if (!maybe_result->ToObject(&result)) return maybe_result; | |
+ } | |
+ | |
+ // String maps are all immortal immovable objects. | |
+ reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map); | |
+ // Set length and hash fields of the allocated string. | |
+ String* answer = String::cast(result); | |
+ answer->set_length(str.length()); | |
+ answer->set_hash_field(hash_field); | |
+ | |
+ ASSERT_EQ(size, answer->Size()); | |
+ | |
+ // Fill in the characters. | |
+ memcpy(answer->address() + SeqAsciiString::kHeaderSize, | |
+ str.start(), str.length()); | |
+ | |
+ return answer; | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str, | |
+ uint32_t hash_field) { | |
+ if (str.length() > SeqTwoByteString::kMaxLength) { | |
+ return Failure::OutOfMemoryException(); | |
+ } | |
+ // Compute map and object size. | |
+ Map* map = symbol_map(); | |
+ int size = SeqTwoByteString::SizeFor(str.length()); | |
+ | |
+ // Allocate string. | |
+ Object* result; | |
+ { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) | |
+ ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | |
+ : old_data_space_->AllocateRaw(size); | |
+ if (!maybe_result->ToObject(&result)) return maybe_result; | |
+ } | |
+ | |
+ reinterpret_cast<HeapObject*>(result)->set_map(map); | |
+ // Set length and hash fields of the allocated string. | |
+ String* answer = String::cast(result); | |
+ answer->set_length(str.length()); | |
+ answer->set_hash_field(hash_field); | |
+ | |
+ ASSERT_EQ(size, answer->Size()); | |
+ | |
+ // Fill in the characters. | |
+ memcpy(answer->address() + SeqTwoByteString::kHeaderSize, | |
+ str.start(), str.length() * kUC16Size); | |
+ | |
+ return answer; | |
+} | |
+ | |
+MaybeObject* Heap::CopyFixedArray(FixedArray* src) { | |
+ return CopyFixedArrayWithMap(src, src->map()); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) { | |
+ return CopyFixedDoubleArrayWithMap(src, src->map()); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateRaw(int size_in_bytes, | |
+ AllocationSpace space, | |
+ AllocationSpace retry_space) { | |
+ ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | |
+ ASSERT(space != NEW_SPACE || | |
+ retry_space == OLD_POINTER_SPACE || | |
+ retry_space == OLD_DATA_SPACE || | |
+ retry_space == LO_SPACE); | |
+#ifdef DEBUG | |
+ if (FLAG_gc_interval >= 0 && | |
+ !disallow_allocation_failure_ && | |
+ Heap::allocation_timeout_-- <= 0) { | |
+ return Failure::RetryAfterGC(space); | |
+ } | |
+ isolate_->counters()->objs_since_last_full()->Increment(); | |
+ isolate_->counters()->objs_since_last_young()->Increment(); | |
+#endif | |
+ MaybeObject* result; | |
+ if (NEW_SPACE == space) { | |
+ result = new_space_.AllocateRaw(size_in_bytes); | |
+ if (always_allocate() && result->IsFailure()) { | |
+ space = retry_space; | |
+ } else { | |
+ return result; | |
+ } | |
+ } | |
+ | |
+ if (OLD_POINTER_SPACE == space) { | |
+ result = old_pointer_space_->AllocateRaw(size_in_bytes); | |
+ } else if (OLD_DATA_SPACE == space) { | |
+ result = old_data_space_->AllocateRaw(size_in_bytes); | |
+ } else if (CODE_SPACE == space) { | |
+ result = code_space_->AllocateRaw(size_in_bytes); | |
+ } else if (LO_SPACE == space) { | |
+ result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE); | |
+ } else if (CELL_SPACE == space) { | |
+ result = cell_space_->AllocateRaw(size_in_bytes); | |
+ } else { | |
+ ASSERT(MAP_SPACE == space); | |
+ result = map_space_->AllocateRaw(size_in_bytes); | |
+ } | |
+ if (result->IsFailure()) old_gen_exhausted_ = true; | |
+ return result; | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::NumberFromInt32( | |
+ int32_t value, PretenureFlag pretenure) { | |
+ if (Smi::IsValid(value)) return Smi::FromInt(value); | |
+ // Bypass NumberFromDouble to avoid various redundant checks. | |
+ return AllocateHeapNumber(FastI2D(value), pretenure); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::NumberFromUint32( | |
+ uint32_t value, PretenureFlag pretenure) { | |
+ if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) { | |
+ return Smi::FromInt((int32_t)value); | |
+ } | |
+ // Bypass NumberFromDouble to avoid various redundant checks. | |
+ return AllocateHeapNumber(FastUI2D(value), pretenure); | |
+} | |
+ | |
+ | |
+void Heap::FinalizeExternalString(String* string) { | |
+ ASSERT(string->IsExternalString()); | |
+ v8::String::ExternalStringResourceBase** resource_addr = | |
+ reinterpret_cast<v8::String::ExternalStringResourceBase**>( | |
+ reinterpret_cast<byte*>(string) + | |
+ ExternalString::kResourceOffset - | |
+ kHeapObjectTag); | |
+ | |
+ // Dispose of the C++ object if it has not already been disposed. | |
+ if (*resource_addr != NULL) { | |
+ (*resource_addr)->Dispose(); | |
+ *resource_addr = NULL; | |
+ } | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateRawMap() { | |
+#ifdef DEBUG | |
+ isolate_->counters()->objs_since_last_full()->Increment(); | |
+ isolate_->counters()->objs_since_last_young()->Increment(); | |
+#endif | |
+ MaybeObject* result = map_space_->AllocateRaw(Map::kSize); | |
+ if (result->IsFailure()) old_gen_exhausted_ = true; | |
+#ifdef DEBUG | |
+ if (!result->IsFailure()) { | |
+ // Maps have their own alignment. | |
+ CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) == | |
+ static_cast<intptr_t>(kHeapObjectTag)); | |
+ } | |
+#endif | |
+ return result; | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::AllocateRawCell() { | |
+#ifdef DEBUG | |
+ isolate_->counters()->objs_since_last_full()->Increment(); | |
+ isolate_->counters()->objs_since_last_young()->Increment(); | |
+#endif | |
+ MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize); | |
+ if (result->IsFailure()) old_gen_exhausted_ = true; | |
+ return result; | |
+} | |
+ | |
+ | |
+bool Heap::InNewSpace(Object* object) { | |
+ bool result = new_space_.Contains(object); | |
+ ASSERT(!result || // Either not in new space | |
+ gc_state_ != NOT_IN_GC || // ... or in the middle of GC | |
+ InToSpace(object)); // ... or in to-space (where we allocate). | |
+ return result; | |
+} | |
+ | |
+ | |
+bool Heap::InNewSpace(Address addr) { | |
+ return new_space_.Contains(addr); | |
+} | |
+ | |
+ | |
+bool Heap::InFromSpace(Object* object) { | |
+ return new_space_.FromSpaceContains(object); | |
+} | |
+ | |
+ | |
+bool Heap::InToSpace(Object* object) { | |
+ return new_space_.ToSpaceContains(object); | |
+} | |
+ | |
+ | |
+bool Heap::OldGenerationAllocationLimitReached() { | |
+ if (!incremental_marking()->IsStopped()) return false; | |
+ return OldGenerationSpaceAvailable() < 0; | |
+} | |
+ | |
+ | |
+bool Heap::ShouldBePromoted(Address old_address, int object_size) { | |
+ // An object should be promoted if: | |
+ // - the object has survived a scavenge operation or | |
+ // - to space is already 25% full. | |
+ NewSpacePage* page = NewSpacePage::FromAddress(old_address); | |
+ Address age_mark = new_space_.age_mark(); | |
+ bool below_mark = page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) && | |
+ (!page->ContainsLimit(age_mark) || old_address < age_mark); | |
+ return below_mark || (new_space_.Size() + object_size) >= | |
+ (new_space_.EffectiveCapacity() >> 2); | |
+} | |
+ | |
+ | |
+void Heap::RecordWrite(Address address, int offset) { | |
+ if (!InNewSpace(address)) store_buffer_.Mark(address + offset); | |
+} | |
+ | |
+ | |
+void Heap::RecordWrites(Address address, int start, int len) { | |
+ if (!InNewSpace(address)) { | |
+ for (int i = 0; i < len; i++) { | |
+ store_buffer_.Mark(address + start + i * kPointerSize); | |
+ } | |
+ } | |
+} | |
+ | |
+ | |
+OldSpace* Heap::TargetSpace(HeapObject* object) { | |
+ InstanceType type = object->map()->instance_type(); | |
+ AllocationSpace space = TargetSpaceId(type); | |
+ return (space == OLD_POINTER_SPACE) | |
+ ? old_pointer_space_ | |
+ : old_data_space_; | |
+} | |
+ | |
+ | |
+AllocationSpace Heap::TargetSpaceId(InstanceType type) { | |
+ // Heap numbers and sequential strings are promoted to old data space, all | |
+ // other object types are promoted to old pointer space. We do not use | |
+ // object->IsHeapNumber() and object->IsSeqString() because we already | |
+ // know that object has the heap object tag. | |
+ | |
+ // These objects are never allocated in new space. | |
+ ASSERT(type != MAP_TYPE); | |
+ ASSERT(type != CODE_TYPE); | |
+ ASSERT(type != ODDBALL_TYPE); | |
+ ASSERT(type != JS_GLOBAL_PROPERTY_CELL_TYPE); | |
+ | |
+ if (type < FIRST_NONSTRING_TYPE) { | |
+ // There are four string representations: sequential strings, external | |
+ // strings, cons strings, and sliced strings. | |
+ // Only the latter two contain non-map-word pointers to heap objects. | |
+ return ((type & kIsIndirectStringMask) == kIsIndirectStringTag) | |
+ ? OLD_POINTER_SPACE | |
+ : OLD_DATA_SPACE; | |
+ } else { | |
+ return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE; | |
+ } | |
+} | |
+ | |
+ | |
+void Heap::CopyBlock(Address dst, Address src, int byte_size) { | |
+ CopyWords(reinterpret_cast<Object**>(dst), | |
+ reinterpret_cast<Object**>(src), | |
+ byte_size / kPointerSize); | |
+} | |
+ | |
+ | |
+void Heap::MoveBlock(Address dst, Address src, int byte_size) { | |
+ ASSERT(IsAligned(byte_size, kPointerSize)); | |
+ | |
+ int size_in_words = byte_size / kPointerSize; | |
+ | |
+ if ((dst < src) || (dst >= (src + byte_size))) { | |
+ Object** src_slot = reinterpret_cast<Object**>(src); | |
+ Object** dst_slot = reinterpret_cast<Object**>(dst); | |
+ Object** end_slot = src_slot + size_in_words; | |
+ | |
+ while (src_slot != end_slot) { | |
+ *dst_slot++ = *src_slot++; | |
+ } | |
+ } else { | |
+ memmove(dst, src, byte_size); | |
+ } | |
+} | |
+ | |
+ | |
+void Heap::ScavengePointer(HeapObject** p) { | |
+ ScavengeObject(p, *p); | |
+} | |
+ | |
+ | |
+void Heap::ScavengeObject(HeapObject** p, HeapObject* object) { | |
+ ASSERT(HEAP->InFromSpace(object)); | |
+ | |
+ // We use the first word (where the map pointer usually is) of a heap | |
+ // object to record the forwarding pointer. A forwarding pointer can | |
+ // point to an old space, the code space, or the to space of the new | |
+ // generation. | |
+ MapWord first_word = object->map_word(); | |
+ | |
+ // If the first word is a forwarding address, the object has already been | |
+ // copied. | |
+ if (first_word.IsForwardingAddress()) { | |
+ HeapObject* dest = first_word.ToForwardingAddress(); | |
+ ASSERT(HEAP->InFromSpace(*p)); | |
+ *p = dest; | |
+ return; | |
+ } | |
+ | |
+ // Call the slow part of scavenge object. | |
+ return ScavengeObjectSlow(p, object); | |
+} | |
+ | |
+ | |
+bool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason) { | |
+ const char* collector_reason = NULL; | |
+ GarbageCollector collector = SelectGarbageCollector(space, &collector_reason); | |
+ return CollectGarbage(space, collector, gc_reason, collector_reason); | |
+} | |
+ | |
+ | |
+MaybeObject* Heap::PrepareForCompare(String* str) { | |
+ // Always flatten small strings and force flattening of long strings | |
+ // after we have accumulated a certain amount we failed to flatten. | |
+ static const int kMaxAlwaysFlattenLength = 32; | |
+ static const int kFlattenLongThreshold = 16*KB; | |
+ | |
+ const int length = str->length(); | |
+ MaybeObject* obj = str->TryFlatten(); | |
+ if (length <= kMaxAlwaysFlattenLength || | |
+ unflattened_strings_length_ >= kFlattenLongThreshold) { | |
+ return obj; | |
+ } | |
+ if (obj->IsFailure()) { | |
+ unflattened_strings_length_ += length; | |
+ } | |
+ return str; | |
+} | |
+ | |
+ | |
+intptr_t Heap::AdjustAmountOfExternalAllocatedMemory( | |
+ intptr_t change_in_bytes) { | |
+ ASSERT(HasBeenSetUp()); | |
+ intptr_t amount = amount_of_external_allocated_memory_ + change_in_bytes; | |
+ if (change_in_bytes >= 0) { | |
+ // Avoid overflow. | |
+ if (amount > amount_of_external_allocated_memory_) { | |
+ amount_of_external_allocated_memory_ = amount; | |
+ } | |
+ intptr_t amount_since_last_global_gc = | |
+ amount_of_external_allocated_memory_ - | |
+ amount_of_external_allocated_memory_at_last_global_gc_; | |
+ if (amount_since_last_global_gc > external_allocation_limit_) { | |
+ //CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached"); | |
+ } | |
+ } else { | |
+ // Avoid underflow. | |
+ if (amount >= 0) { | |
+ amount_of_external_allocated_memory_ = amount; | |
+ } | |
+ } | |
+ ASSERT(amount_of_external_allocated_memory_ >= 0); | |
+ return amount_of_external_allocated_memory_; | |
+} | |
+ | |
+ | |
+void Heap::SetLastScriptId(Object* last_script_id) { | |
+ roots_[kLastScriptIdRootIndex] = last_script_id; | |
+} | |
+ | |
+ | |
+Isolate* Heap::isolate() { | |
+ return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) - | |
+ reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4); | |
+} | |
+ | |
+ | |
+#ifdef DEBUG | |
+#define GC_GREEDY_CHECK() \ | |
+ if (FLAG_gc_greedy) HEAP->GarbageCollectionGreedyCheck() | |
+#else | |
+#define GC_GREEDY_CHECK() { } | |
+#endif | |
+ | |
+// Calls the FUNCTION_CALL function and retries it up to three times | |
+// to guarantee that any allocations performed during the call will | |
+// succeed if there's enough memory. | |
+ | |
+// Warning: Do not use the identifiers __object__, __maybe_object__ or | |
+// __scope__ in a call to this macro. | |
+ | |
+#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)\ | |
+ do { \ | |
+ GC_GREEDY_CHECK(); \ | |
+ MaybeObject* __maybe_object__ = FUNCTION_CALL; \ | |
+ Object* __object__ = NULL; \ | |
+ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
+ if (__maybe_object__->IsOutOfMemory()) { \ | |
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\ | |
+ } \ | |
+ if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ | |
+ ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ | |
+ allocation_space(), \ | |
+ "allocation failure"); \ | |
+ __maybe_object__ = FUNCTION_CALL; \ | |
+ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
+ if (__maybe_object__->IsOutOfMemory()) { \ | |
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\ | |
+ } \ | |
+ if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ | |
+ ISOLATE->counters()->gc_last_resort_from_handles()->Increment(); \ | |
+ ISOLATE->heap()->CollectAllAvailableGarbage("last resort gc"); \ | |
+ { \ | |
+ AlwaysAllocateScope __scope__; \ | |
+ __maybe_object__ = FUNCTION_CALL; \ | |
+ } \ | |
+ if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ | |
+ if (__maybe_object__->IsOutOfMemory() || \ | |
+ __maybe_object__->IsRetryAfterGC()) { \ | |
+ /* TODO(1181417): Fix this. */ \ | |
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\ | |
+ } \ | |
+ RETURN_EMPTY; \ | |
+ } while (false) | |
+ | |
+ | |
+#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ | |
+ CALL_AND_RETRY(ISOLATE, \ | |
+ FUNCTION_CALL, \ | |
+ return Handle<TYPE>(TYPE::cast(__object__), ISOLATE), \ | |
+ return Handle<TYPE>()) | |
+ | |
+ | |
+#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ | |
+ CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) | |
+ | |
+ | |
+#ifdef DEBUG | |
+ | |
+inline bool Heap::allow_allocation(bool new_state) { | |
+ bool old = allocation_allowed_; | |
+ allocation_allowed_ = new_state; | |
+ return old; | |
+} | |
+ | |
+#endif | |
+ | |
+ | |
+void ExternalStringTable::AddString(String* string) { | |
+ ASSERT(string->IsExternalString()); | |
+ if (heap_->InNewSpace(string)) { | |
+ new_space_strings_.Add(string); | |
+ } else { | |
+ old_space_strings_.Add(string); | |
+ } | |
+} | |
+ | |
+ | |
+void ExternalStringTable::Iterate(ObjectVisitor* v) { | |
+ if (!new_space_strings_.is_empty()) { | |
+ Object** start = &new_space_strings_[0]; | |
+ v->VisitPointers(start, start + new_space_strings_.length()); | |
+ } | |
+ if (!old_space_strings_.is_empty()) { | |
+ Object** start = &old_space_strings_[0]; | |
+ v->VisitPointers(start, start + old_space_strings_.length()); | |
+ } | |
+} | |
+ | |
+ | |
+// Verify() is inline to avoid ifdef-s around its calls in release | |
+// mode. | |
+void ExternalStringTable::Verify() { | |
+#ifdef DEBUG | |
+ for (int i = 0; i < new_space_strings_.length(); ++i) { | |
+ ASSERT(heap_->InNewSpace(new_space_strings_[i])); | |
+ ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_the_hole_value()); | |
+ } | |
+ for (int i = 0; i < old_space_strings_.length(); ++i) { | |
+ ASSERT(!heap_->InNewSpace(old_space_strings_[i])); | |
+ ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_the_hole_value()); | |
+ } | |
+#endif | |
+} | |
+ | |
+ | |
+void ExternalStringTable::AddOldString(String* string) { | |
+ ASSERT(string->IsExternalString()); | |
+ ASSERT(!heap_->InNewSpace(string)); | |
+ old_space_strings_.Add(string); | |
+} | |
+ | |
+ | |
+void ExternalStringTable::ShrinkNewStrings(int position) { | |
+ new_space_strings_.Rewind(position); | |
+ if (FLAG_verify_heap) { | |
+ Verify(); | |
+ } | |
+} | |
+ | |
+ | |
+void Heap::ClearInstanceofCache() { | |
+ set_instanceof_cache_function(the_hole_value()); | |
+} | |
+ | |
+ | |
+Object* Heap::ToBoolean(bool condition) { | |
+ return condition ? true_value() : false_value(); | |
+} | |
+ | |
+ | |
+void Heap::CompletelyClearInstanceofCache() { | |
+ set_instanceof_cache_map(the_hole_value()); | |
+ set_instanceof_cache_function(the_hole_value()); | |
+} | |
+ | |
+ | |
+MaybeObject* TranscendentalCache::Get(Type type, double input) { | |
+ SubCache* cache = caches_[type]; | |
+ if (cache == NULL) { | |
+ caches_[type] = cache = new SubCache(type); | |
+ } | |
+ return cache->Get(input); | |
+} | |
+ | |
+ | |
+Address TranscendentalCache::cache_array_address() { | |
+ return reinterpret_cast<Address>(caches_); | |
+} | |
+ | |
+ | |
+double TranscendentalCache::SubCache::Calculate(double input) { | |
+ switch (type_) { | |
+ case ACOS: | |
+ return acos(input); | |
+ case ASIN: | |
+ return asin(input); | |
+ case ATAN: | |
+ return atan(input); | |
+ case COS: | |
+ return fast_cos(input); | |
+ case EXP: | |
+ return exp(input); | |
+ case LOG: | |
+ return fast_log(input); | |
+ case SIN: | |
+ return fast_sin(input); | |
+ case TAN: | |
+ return fast_tan(input); | |
+ default: | |
+ return 0.0; // Never happens. | |
+ } | |
+} | |
+ | |
+ | |
+MaybeObject* TranscendentalCache::SubCache::Get(double input) { | |
+ Converter c; | |
+ c.dbl = input; | |
+ int hash = Hash(c); | |
+ Element e = elements_[hash]; | |
+ if (e.in[0] == c.integers[0] && | |
+ e.in[1] == c.integers[1]) { | |
+ ASSERT(e.output != NULL); | |
+ isolate_->counters()->transcendental_cache_hit()->Increment(); | |
+ return e.output; | |
+ } | |
+ double answer = Calculate(input); | |
+ isolate_->counters()->transcendental_cache_miss()->Increment(); | |
+ Object* heap_number; | |
+ { MaybeObject* maybe_heap_number = | |
+ isolate_->heap()->AllocateHeapNumber(answer); | |
+ if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number; | |
+ } | |
+ elements_[hash].in[0] = c.integers[0]; | |
+ elements_[hash].in[1] = c.integers[1]; | |
+ elements_[hash].output = heap_number; | |
+ return heap_number; | |
+} | |
+ | |
+ | |
+AlwaysAllocateScope::AlwaysAllocateScope() { | |
+ // We shouldn't hit any nested scopes, because that requires | |
+ // non-handle code to call handle code. The code still works but | |
+ // performance will degrade, so we want to catch this situation | |
+ // in debug mode. | |
+ ASSERT(HEAP->always_allocate_scope_depth_ == 0); | |
+ HEAP->always_allocate_scope_depth_++; | |
+} | |
+ | |
+ | |
+AlwaysAllocateScope::~AlwaysAllocateScope() { | |
+ HEAP->always_allocate_scope_depth_--; | |
+ ASSERT(HEAP->always_allocate_scope_depth_ == 0); | |
+} | |
+ | |
+ | |
+LinearAllocationScope::LinearAllocationScope() { | |
+ HEAP->linear_allocation_scope_depth_++; | |
+} | |
+ | |
+ | |
+LinearAllocationScope::~LinearAllocationScope() { | |
+ HEAP->linear_allocation_scope_depth_--; | |
+ ASSERT(HEAP->linear_allocation_scope_depth_ >= 0); | |
+} | |
+ | |
+ | |
+#ifdef DEBUG | |
+void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) { | |
+ for (Object** current = start; current < end; current++) { | |
+ if ((*current)->IsHeapObject()) { | |
+ HeapObject* object = HeapObject::cast(*current); | |
+ ASSERT(HEAP->Contains(object)); | |
+ ASSERT(object->map()->IsMap()); | |
+ } | |
+ } | |
+} | |
+#endif | |
+ | |
+ | |
+double GCTracer::SizeOfHeapObjects() { | |
+ return (static_cast<double>(HEAP->SizeOfObjects())) / MB; | |
+} | |
+ | |
+ | |
+#ifdef DEBUG | |
+DisallowAllocationFailure::DisallowAllocationFailure() { | |
+ old_state_ = HEAP->disallow_allocation_failure_; | |
+ HEAP->disallow_allocation_failure_ = true; | |
+} | |
+ | |
+ | |
+DisallowAllocationFailure::~DisallowAllocationFailure() { | |
+ HEAP->disallow_allocation_failure_ = old_state_; | |
+} | |
+#endif | |
+ | |
+ | |
+#ifdef DEBUG | |
+AssertNoAllocation::AssertNoAllocation() { | |
+ old_state_ = HEAP->allow_allocation(false); | |
+} | |
+ | |
+ | |
+AssertNoAllocation::~AssertNoAllocation() { | |
+ HEAP->allow_allocation(old_state_); | |
+} | |
+ | |
+ | |
+DisableAssertNoAllocation::DisableAssertNoAllocation() { | |
+ old_state_ = HEAP->allow_allocation(true); | |
+} | |
+ | |
+ | |
+DisableAssertNoAllocation::~DisableAssertNoAllocation() { | |
+ HEAP->allow_allocation(old_state_); | |
+} | |
+ | |
+#else | |
+ | |
+AssertNoAllocation::AssertNoAllocation() { } | |
+AssertNoAllocation::~AssertNoAllocation() { } | |
+DisableAssertNoAllocation::DisableAssertNoAllocation() { } | |
+DisableAssertNoAllocation::~DisableAssertNoAllocation() { } | |
+ | |
+#endif | |
+ | |
+ | |
+} } // namespace v8::internal | |
+ | |
+#endif // V8_HEAP_INL_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment