Skip to content

Instantly share code, notes, and snippets.

@mashihua
Created April 17, 2012 04:09
Show Gist options
  • Save mashihua/2403390 to your computer and use it in GitHub Desktop.
Save mashihua/2403390 to your computer and use it in GitHub Desktop.
Patch for v8
#Escape the 1.4GB V8 heap limit patch for Version 3.10.2
Usage: patch -p0 < v8.patch
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