diff options
author | isaacs <i@izs.me> | 2012-06-09 08:09:42 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-06-09 08:09:42 -0700 |
commit | 940a6863ead6622e5439e07be631359c31e63b68 (patch) | |
tree | c5aa25c048b8f0fd622d4c42fa134ca645fcbcd7 | |
parent | 569acea0eefed2c7da7453b7dcef6ff47491ca1c (diff) | |
download | node-new-940a6863ead6622e5439e07be631359c31e63b68.tar.gz |
Roll V8 back to 3.9.24.31
253 files changed, 5143 insertions, 22142 deletions
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 6e46b3d621..dfefad129f 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -23,7 +23,6 @@ Daniel James <dnljms@gmail.com> Dineel D Sule <dsule@codeaurora.org> Erich Ocean <erich.ocean@me.com> Fedor Indutny <fedor@indutny.com> -Filipe David Manana <fdmanana@gmail.com> Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com> Jan de Mooij <jandemooij@gmail.com> Jay Freeman <saurik@saurik.com> diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index 09c02378f5..2240ec0e68 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,163 +1,3 @@ -2012-05-03: Version 3.10.8 - - Enabled MIPS cross-compilation. - - Ensured reload of elements pointer in StoreFastDoubleElement stub. - (Chromium issue 125515) - - Fixed corner cases in truncation behavior when storing to - TypedArrays. (issue 2110) - - Fixed failure to properly recognize and report out-of-memory - conditions when allocating code space pages. (Chromium issue - 118625) - - Fixed idle notifications to perform a round of incremental GCs - after context disposal. (issue 2107) - - Fixed preparser for try statement. (issue 2109) - - Performance and stability improvements on all platforms. - - -2012-04-30: Version 3.10.7 - - Performance and stability improvements on all platforms. - - -2012-04-26: Version 3.10.6 - - Fixed some bugs in accessing details of the last regexp match. - - Fixed source property of empty RegExp objects. (issue 1982) - - Enabled inlining some V8 API functions. - - Performance and stability improvements on all platforms. - - -2012-04-23: Version 3.10.5 - - Put new global var semantics behind a flag until WebKit tests are - cleaned up. - - Enabled stepping into callback passed to builtins. - (Chromium issue 109564) - - Performance and stability improvements on all platforms. - - -2012-04-19: Version 3.10.4 - - Fixed issues when stressing compaction with WeakMaps. - - Fixed missing GVN flag for new-space promotion. (Chromium issue 123919) - - Simplify invocation sequence at monomorphic function invocation sites. - (issue 2079) - - Performance and stability improvements on all platforms. - - -2012-04-17: Version 3.10.3 - - Fixed several bugs in heap profiles (including issue 2078). - - Throw syntax errors on illegal escape sequences. - - Implemented rudimentary module linking (behind --harmony flag) - - Implemented ES5 erratum: Global declarations should shadow - inherited properties. - - Made handling of const more consistent when combined with 'eval' - and 'with'. - - Fixed V8 on MinGW-x64 (issue 2026). - - Performance and stability improvements on all platforms. - - -2012-04-13: Version 3.10.2 - - Fixed native ARM build (issues 1744, 539) - - Return LOOKUP variable instead of CONTEXT for non-context allocated - outer scope parameters (Chromium issue 119609). - - Fixed regular and ElementsKind transitions interfering with each other - (Chromium issue 122271). - - Improved performance of keyed loads/stores which have a HeapNumber - index (issues 1388, 1295). - - Fixed WeakMap processing for evacuation candidates (issue 2060). - - Bailout on possible direct eval calls (Chromium issue 122681). - - Do not assume that names of function expressions are context-allocated - (issue 2051). - - Performance and stability improvements on all platforms. - - -2012-04-10: Version 3.10.1 - - Fixed bug with arguments object in inlined functions (issue 2045). - - Fixed performance bug with lazy initialization (Chromium issue - 118686). - - Added suppport for Mac OS X 64bit builds with GYP. - (Patch contributed by Filipe David Manana <fdmanana@gmail.com>) - - Fixed bug with hidden properties (issue 2034). - - Fixed a performance bug when reloading pages (Chromium issue 117767, - V8 issue 1902). - - Fixed bug when optimizing throw in top-level code (issue 2054). - - Fixed two bugs with array literals (issue 2055, Chromium issue 121407). - - Fixed bug with Math.min/Math.max with NaN inputs (issue 2056). - - Fixed a bug with the new runtime profiler (Chromium issue 121147). - - Fixed compilation of V8 using uClibc. - - Optimized boot-up memory use. - - Optimized regular expressions. - - -2012-03-30: Version 3.10.0 - - Fixed store IC writability check in strict mode - (Chromium issue 120099). - - Resynchronize timers if the Windows system time was changed. - (Chromium issue 119815) - - Removed "-mfloat-abi=hard" from host compiler cflags when building for - hardfp ARM - (https://code.google.com/p/chrome-os-partner/issues/detail?id=8539) - - Fixed edge case for case independent regexp character classes - (issue 2032). - - Reset function info counters after context disposal. - (Chromium issue 117767, V8 issue 1902) - - Fixed missing write barrier in CopyObjectToObjectElements. - (Chromium issue 119926) - - Fixed missing bounds check in HasElementImpl. - (Chromium issue 119925) - - Performance and stability improvements on all platforms. - - 2012-03-23: Version 3.9.24 Activated count-based profiler for ARM. diff --git a/deps/v8/Makefile b/deps/v8/Makefile index 277c1f786d..2f86c512e4 100644 --- a/deps/v8/Makefile +++ b/deps/v8/Makefile @@ -137,6 +137,12 @@ ENVFILE = $(OUTDIR)/environment # Target definitions. "all" is the default. all: $(MODES) +# Special target for the buildbots to use. Depends on $(OUTDIR)/Makefile +# having been created before. +buildbot: + $(MAKE) -C "$(OUTDIR)" BUILDTYPE=$(BUILDTYPE) \ + builddir="$(abspath $(OUTDIR))/$(BUILDTYPE)" + # Compile targets. MODES and ARCHES are convenience targets. .SECONDEXPANSION: $(MODES): $(addsuffix .$$@,$(DEFAULT_ARCHES)) @@ -144,21 +150,21 @@ $(MODES): $(addsuffix .$$@,$(DEFAULT_ARCHES)) $(ARCHES): $(addprefix $$@.,$(MODES)) # Defines how to build a particular target (e.g. ia32.release). -$(BUILDS): $(OUTDIR)/Makefile.$$(basename $$@) - @$(MAKE) -C "$(OUTDIR)" -f Makefile.$(basename $@) \ +$(BUILDS): $(OUTDIR)/Makefile-$$(basename $$@) + @$(MAKE) -C "$(OUTDIR)" -f Makefile-$(basename $@) \ CXX="$(CXX)" LINK="$(LINK)" \ BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \ python -c "print raw_input().capitalize()") \ builddir="$(shell pwd)/$(OUTDIR)/$@" -native: $(OUTDIR)/Makefile.native - @$(MAKE) -C "$(OUTDIR)" -f Makefile.native \ +native: $(OUTDIR)/Makefile-native + @$(MAKE) -C "$(OUTDIR)" -f Makefile-native \ CXX="$(CXX)" LINK="$(LINK)" BUILDTYPE=Release \ builddir="$(shell pwd)/$(OUTDIR)/$@" # TODO(jkummerow): add "android.debug" when we need it. -android android.release: $(OUTDIR)/Makefile.android - @$(MAKE) -C "$(OUTDIR)" -f Makefile.android \ +android android.release: $(OUTDIR)/Makefile-android + @$(MAKE) -C "$(OUTDIR)" -f Makefile-android \ CXX="$(ANDROID_TOOL_PREFIX)-g++" \ AR="$(ANDROID_TOOL_PREFIX)-ar" \ RANLIB="$(ANDROID_TOOL_PREFIX)-ranlib" \ @@ -191,40 +197,55 @@ native.check: native --arch-and-mode=. $(TESTFLAGS) # Clean targets. You can clean each architecture individually, or everything. -$(addsuffix .clean,$(ARCHES)) android.clean: - rm -f $(OUTDIR)/Makefile.$(basename $@) +$(addsuffix .clean,$(ARCHES)): + rm -f $(OUTDIR)/Makefile-$(basename $@) rm -rf $(OUTDIR)/$(basename $@).release rm -rf $(OUTDIR)/$(basename $@).debug - find $(OUTDIR) -regex '.*\(host\|target\).$(basename $@)\.mk' -delete + find $(OUTDIR) -regex '.*\(host\|target\)-$(basename $@)\.mk' -delete native.clean: - rm -f $(OUTDIR)/Makefile.native + rm -f $(OUTDIR)/Makefile-native rm -rf $(OUTDIR)/native - find $(OUTDIR) -regex '.*\(host\|target\).native\.mk' -delete + find $(OUTDIR) -regex '.*\(host\|target\)-native\.mk' -delete + +android.clean: + rm -f $(OUTDIR)/Makefile-android + rm -rf $(OUTDIR)/android.release + find $(OUTDIR) -regex '.*\(host\|target\)-android\.mk' -delete -clean: $(addsuffix .clean,$(ARCHES)) native.clean android.clean +clean: $(addsuffix .clean,$(ARCHES)) native.clean # GYP file generation targets. -MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ARCHES)) -$(MAKEFILES): $(GYPFILES) $(ENVFILE) - GYP_GENERATORS=make \ +$(OUTDIR)/Makefile-ia32: $(GYPFILES) $(ENVFILE) + build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ + -Ibuild/standalone.gypi --depth=. -Dtarget_arch=ia32 \ + -S-ia32 $(GYPFLAGS) + +$(OUTDIR)/Makefile-x64: $(GYPFILES) $(ENVFILE) + build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ + -Ibuild/standalone.gypi --depth=. -Dtarget_arch=x64 \ + -S-x64 $(GYPFLAGS) + +$(OUTDIR)/Makefile-arm: $(GYPFILES) $(ENVFILE) build/armu.gypi + build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ + -Ibuild/standalone.gypi --depth=. -Ibuild/armu.gypi \ + -S-arm $(GYPFLAGS) + +$(OUTDIR)/Makefile-mips: $(GYPFILES) $(ENVFILE) build/mipsu.gypi build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ - -Ibuild/standalone.gypi --depth=. \ - -Dv8_target_arch=$(subst .,,$(suffix $@)) \ - -S.$(subst .,,$(suffix $@)) $(GYPFLAGS) + -Ibuild/standalone.gypi --depth=. -Ibuild/mipsu.gypi \ + -S-mips $(GYPFLAGS) -$(OUTDIR)/Makefile.native: $(GYPFILES) $(ENVFILE) - GYP_GENERATORS=make \ +$(OUTDIR)/Makefile-native: $(GYPFILES) $(ENVFILE) build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ - -Ibuild/standalone.gypi --depth=. -S.native $(GYPFLAGS) + -Ibuild/standalone.gypi --depth=. -S-native $(GYPFLAGS) -$(OUTDIR)/Makefile.android: $(GYPFILES) $(ENVFILE) build/android.gypi \ +$(OUTDIR)/Makefile-android: $(GYPFILES) $(ENVFILE) build/android.gypi \ must-set-ANDROID_NDK_ROOT - GYP_GENERATORS=make \ CC="${ANDROID_TOOL_PREFIX}-gcc" \ build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \ -Ibuild/standalone.gypi --depth=. -Ibuild/android.gypi \ - -S.android $(GYPFLAGS) + -S-android $(GYPFLAGS) must-set-ANDROID_NDK_ROOT: ifndef ANDROID_NDK_ROOT @@ -240,10 +261,9 @@ $(ENVFILE): $(ENVFILE).new # Stores current GYPFLAGS in a file. $(ENVFILE).new: - @mkdir -p $(OUTDIR); echo "GYPFLAGS=$(GYPFLAGS)" > $(ENVFILE).new; \ - echo "CXX=$(CXX)" >> $(ENVFILE).new + @mkdir -p $(OUTDIR); echo "GYPFLAGS=$(GYPFLAGS)" > $(ENVFILE).new; # Dependencies. dependencies: svn checkout --force http://gyp.googlecode.com/svn/trunk build/gyp \ - --revision 1282 + --revision 1026 diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index 34d0efc5ff..b0d1344700 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -1601,4 +1601,17 @@ except: pass +def WarnAboutDeprecation(): + print """ +####################################################### +# WARNING: Building V8 with SCons is deprecated and # +# will not work much longer. Please switch to using # +# the GYP-based build now. Instructions are at # +# http://code.google.com/p/v8/wiki/BuildingWithGYP. # +####################################################### + """ + +WarnAboutDeprecation() +import atexit +atexit.register(WarnAboutDeprecation) Build() diff --git a/deps/v8/build/armu.gypi b/deps/v8/build/armu.gypi new file mode 100644 index 0000000000..d15b8ab705 --- /dev/null +++ b/deps/v8/build/armu.gypi @@ -0,0 +1,36 @@ +# Copyright 2011 the V8 project authors. All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +{ + 'variables': { + 'target_arch': 'ia32', + 'v8_target_arch': 'arm', + 'armv7': 1, + 'arm_neon': 0, + 'arm_fpu': 'vfpv3', + }, +} diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index f999437783..74a964d4db 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -142,10 +142,8 @@ 'USE_EABI_HARDFLOAT=1', 'CAN_USE_VFP_INSTRUCTIONS', ], - 'target_conditions': [ - ['_toolset=="target"', { - 'cflags': ['-mfloat-abi=hard',], - }], + 'cflags': [ + '-mfloat-abi=hard', ], }, { 'defines': [ @@ -173,11 +171,8 @@ 'defines': [ 'V8_TARGET_ARCH_MIPS', ], - 'variables': { - 'mipscompiler': '<!($(echo ${CXX:-$(which g++)}) -v 2>&1 | grep -q "^Target: mips-" && echo "yes" || echo "no")', - }, 'conditions': [ - ['mipscompiler=="yes"', { + [ 'target_arch=="mips"', { 'target_conditions': [ ['_toolset=="target"', { 'cflags': ['-EL'], @@ -241,19 +236,6 @@ ], }], ], - }, { # Section for OS=="mac". - 'conditions': [ - ['target_arch=="ia32"', { - 'xcode_settings': { - 'ARCHS': ['i386'], - } - }], - ['target_arch=="x64"', { - 'xcode_settings': { - 'ARCHS': ['x86_64'], - } - }], - ], }], ['v8_use_liveobjectlist=="true"', { 'defines': [ @@ -280,16 +262,19 @@ }, }, }], + ['OS=="win" and v8_target_arch=="x64"', { + 'msvs_settings': { + 'VCLinkerTool': { + 'StackReserveSize': '2097152', + }, + }, + }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \ or OS=="netbsd"', { 'conditions': [ - [ 'v8_target_arch!="x64"', { - # Pass -m32 to the compiler iff it understands the flag. - 'variables': { - 'm32flag': '<!((echo | $(echo ${CXX:-$(which g++)}) -m32 -E - > /dev/null 2>&1) && echo "-m32" || true)', - }, - 'cflags': [ '<(m32flag)' ], - 'ldflags': [ '<(m32flag)' ], + [ 'target_arch=="ia32"', { + 'cflags': [ '-m32' ], + 'ldflags': [ '-m32' ], }], [ 'v8_no_strict_aliasing==1', { 'cflags': [ '-fno-strict-aliasing' ], @@ -322,10 +307,6 @@ }, 'VCLinkerTool': { 'LinkIncremental': '2', - # For future reference, the stack size needs to be increased - # when building for Windows 64-bit, otherwise some test cases - # can cause stack overflow. - # 'StackReserveSize': '297152', }, }, 'conditions': [ @@ -336,7 +317,7 @@ 'cflags': [ '-I/usr/pkg/include' ], }], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', { - 'cflags': [ '-Wno-unused-parameter', + 'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter', '-Wnon-virtual-dtor', '-Woverloaded-virtual' ], }], ], @@ -407,12 +388,7 @@ 'VCLinkerTool': { 'LinkIncremental': '1', 'OptimizeReferences': '2', - 'OptimizeForWindows98': '1', 'EnableCOMDATFolding': '2', - # For future reference, the stack size needs to be - # increased when building for Windows 64-bit, otherwise - # some test cases can cause stack overflow. - # 'StackReserveSize': '297152', }, }, }], # OS=="win" diff --git a/deps/v8/build/gyp_v8 b/deps/v8/build/gyp_v8 index a926fe8ca3..6d5c126844 100755 --- a/deps/v8/build/gyp_v8 +++ b/deps/v8/build/gyp_v8 @@ -1,6 +1,6 @@ #!/usr/bin/python # -# Copyright 2012 the V8 project authors. All rights reserved. +# Copyright 2010 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: @@ -38,6 +38,11 @@ import sys script_dir = os.path.dirname(__file__) v8_root = os.path.normpath(os.path.join(script_dir, os.pardir)) +if __name__ == '__main__': + os.chdir(v8_root) + script_dir = os.path.dirname(__file__) + v8_root = '.' + sys.path.insert(0, os.path.join(v8_root, 'tools')) import utils @@ -93,7 +98,7 @@ def additional_include_files(args=[]): result.append(path) # Always include standalone.gypi - AddInclude(os.path.join(script_dir, 'standalone.gypi')) + AddInclude(os.path.join(v8_root, 'build', 'standalone.gypi')) # Optionally add supplemental .gypi files if present. supplements = glob.glob(os.path.join(v8_root, '*', 'supplement.gypi')) @@ -135,7 +140,10 @@ if __name__ == '__main__': # path separators even on Windows due to the use of shlex.split(). args.extend(shlex.split(gyp_file)) else: - args.append(os.path.join(script_dir, 'all.gyp')) + # Note that this must not start with "./" or things break. + # So we rely on having done os.chdir(v8_root) above and use the + # relative path. + args.append(os.path.join('build', 'all.gyp')) args.extend(['-I' + i for i in additional_include_files(args)]) @@ -156,28 +164,6 @@ if __name__ == '__main__': # Generate for the architectures supported on the given platform. gyp_args = list(args) - target_arch = None - for p in gyp_args: - if p.find('-Dtarget_arch=') == 0: - target_arch = p - if target_arch is None: - gyp_args.append('-Dtarget_arch=ia32') if utils.GuessOS() == 'linux': - gyp_args.append('-S.ia32') + gyp_args.append('--generator-output=out') run_gyp(gyp_args) - - if utils.GuessOS() == 'linux': - gyp_args = list(args) - gyp_args.append('-Dtarget_arch=x64') - gyp_args.append('-S.x64') - run_gyp(gyp_args) - - gyp_args = list(args) - gyp_args.append('-Dv8_target_arch=arm') - gyp_args.append('-S.arm') - run_gyp(gyp_args) - - gyp_args = list(args) - gyp_args.append('-Dv8_target_arch=mips') - gyp_args.append('-S.mips') - run_gyp(gyp_args) diff --git a/deps/v8/build/mipsu.gypi b/deps/v8/build/mipsu.gypi new file mode 100644 index 0000000000..637ff841e4 --- /dev/null +++ b/deps/v8/build/mipsu.gypi @@ -0,0 +1,33 @@ +# 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. + +{ + 'variables': { + 'target_arch': 'ia32', + 'v8_target_arch': 'mips', + }, +} diff --git a/deps/v8/build/standalone.gypi b/deps/v8/build/standalone.gypi index dad05ae962..b5707800f8 100644 --- a/deps/v8/build/standalone.gypi +++ b/deps/v8/build/standalone.gypi @@ -71,10 +71,6 @@ 'want_separate_host_toolset': 0, }], ], - # Default ARM variable settings. - 'armv7%': 1, - 'arm_neon%': 0, - 'arm_fpu%': 'vfpv3', }, 'target_defaults': { 'default_configuration': 'Debug', @@ -169,6 +165,9 @@ }, }], # OS=="win" ['OS=="mac"', { + 'xcode_settings': { + 'SYMROOT': '<(DEPTH)/xcodebuild', + }, 'target_defaults': { 'xcode_settings': { 'ALWAYS_SEARCH_USER_PATHS': 'NO', @@ -188,6 +187,7 @@ 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof 'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4 'PREBINDING': 'NO', # No -Wl,-prebind + 'SYMROOT': '<(DEPTH)/xcodebuild', 'USE_HEADERMAP': 'NO', 'OTHER_CFLAGS': [ '-fno-strict-aliasing', diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 8f380f2094..2499bbf050 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -64,7 +64,6 @@ */ namespace v8 { -typedef uint32_t SnapshotObjectId; /** * CpuProfileNode represents a node in a call graph. @@ -275,7 +274,7 @@ class V8EXPORT HeapGraphNode { * Returns node id. For the same heap object, the id remains the same * across all snapshots. */ - SnapshotObjectId GetId() const; + uint64_t GetId() const; /** Returns node's own size, in bytes. */ int GetSelfSize() const; @@ -339,7 +338,7 @@ class V8EXPORT HeapSnapshot { const HeapGraphNode* GetRoot() const; /** Returns a node by its id. */ - const HeapGraphNode* GetNodeById(SnapshotObjectId id) const; + const HeapGraphNode* GetNodeById(uint64_t id) const; /** Returns total nodes count in the snapshot. */ int GetNodesCount() const; @@ -347,9 +346,6 @@ class V8EXPORT HeapSnapshot { /** Returns a node by index. */ const HeapGraphNode* GetNode(int index) const; - /** Returns a max seen JS object Id. */ - SnapshotObjectId GetMaxSnapshotJSObjectId() const; - /** * Deletes the snapshot and removes it from HeapProfiler's list. * All pointers to nodes, edges and paths previously returned become @@ -368,20 +364,16 @@ class V8EXPORT HeapSnapshot { * with the following structure: * * { - * snapshot: { - * title: "...", - * uid: nnn, - * meta: { meta-info }, - * node_count: nnn, - * edge_count: nnn - * }, - * nodes: [nodes array], - * edges: [edges array], - * strings: [strings array] + * snapshot: {title: "...", uid: nnn}, + * nodes: [ + * meta-info (JSON string), + * nodes themselves + * ], + * strings: [strings] * } * - * Nodes reference strings, other nodes, and edges by their indexes - * in corresponding arrays. + * Outgoing node links are stored after each node. Nodes reference strings + * and other nodes by their indexes in corresponding arrays. */ void Serialize(OutputStream* stream, SerializationFormat format) const; }; @@ -413,19 +405,6 @@ class V8EXPORT HeapProfiler { static const HeapSnapshot* FindSnapshot(unsigned uid); /** - * Returns SnapshotObjectId for a heap object referenced by |value| if - * it has been seen by the heap profiler, kUnknownObjectId otherwise. - */ - static SnapshotObjectId GetSnapshotObjectId(Handle<Value> value); - - /** - * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return - * it in case heap profiler cannot find id for the object passed as - * parameter. HeapSnapshot::GetNodeById will always return NULL for such id. - */ - static const SnapshotObjectId kUnknownObjectId = 0; - - /** * Takes a heap snapshot and returns it. Title may be an empty string. * See HeapSnapshot::Type for types description. */ @@ -435,33 +414,6 @@ class V8EXPORT HeapProfiler { ActivityControl* control = NULL); /** - * Starts tracking of heap objects population statistics. After calling - * this method, all heap objects relocations done by the garbage collector - * are being registered. - */ - static void StartHeapObjectsTracking(); - - /** - * Adds a new time interval entry to the aggregated statistics array. The - * time interval entry contains information on the current heap objects - * population size. The method also updates aggregated statistics and - * reports updates for all previous time intervals via the OutputStream - * object. Updates on each time interval are provided as a stream of the - * HeapStatsUpdate structure instances. - * - * StartHeapObjectsTracking must be called before the first call to this - * method. - */ - static void PushHeapObjectsStats(OutputStream* stream); - - /** - * Stops tracking of heap objects population statistics, cleans up all - * collected data. StartHeapObjectsTracking must be called again prior to - * calling PushHeapObjectsStats next time. - */ - static void StopHeapObjectsTracking(); - - /** * Deletes all snapshots taken. All previously returned pointers to * snapshots and their contents become invalid after this call. */ @@ -558,19 +510,6 @@ class V8EXPORT RetainedObjectInfo { // NOLINT }; -/** - * A struct for exporting HeapStats data from V8, using "push" model. - * See HeapProfiler::PushHeapObjectsStats. - */ -struct HeapStatsUpdate { - HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size) - : index(index), count(count), size(size) { } - uint32_t index; // Index of the time interval that was changed. - uint32_t count; // New value of count field for the interval with this index. - uint32_t size; // New value of size field for the interval with this index. -}; - - } // namespace v8 diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 9024531992..33179f5bf0 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -107,7 +107,6 @@ class Data; class AccessorInfo; class StackTrace; class StackFrame; -class Isolate; namespace internal { @@ -863,13 +862,13 @@ class Value : public Data { * Returns true if this value is the undefined value. See ECMA-262 * 4.3.10. */ - inline bool IsUndefined() const; + V8EXPORT bool IsUndefined() const; /** * Returns true if this value is the null value. See ECMA-262 * 4.3.11. */ - inline bool IsNull() const; + V8EXPORT bool IsNull() const; /** * Returns true if this value is true. @@ -983,11 +982,7 @@ class Value : public Data { V8EXPORT bool StrictEquals(Handle<Value> that) const; private: - inline bool QuickIsUndefined() const; - inline bool QuickIsNull() const; inline bool QuickIsString() const; - V8EXPORT bool FullIsUndefined() const; - V8EXPORT bool FullIsNull() const; V8EXPORT bool FullIsString() const; }; @@ -1084,7 +1079,6 @@ class String : public Primitive { * A zero length string. */ V8EXPORT static v8::Local<v8::String> Empty(); - inline static v8::Local<v8::String> Empty(Isolate* isolate); /** * Returns true if the string is external @@ -1242,7 +1236,8 @@ class String : public Primitive { * this function should not otherwise delete or modify the resource. Neither * should the underlying buffer be deallocated or modified except through the * destructor of the external string resource. - */ V8EXPORT static Local<String> NewExternal( + */ + V8EXPORT static Local<String> NewExternal( ExternalAsciiStringResource* resource); /** @@ -1973,13 +1968,10 @@ class Arguments { inline Local<Object> Holder() const; inline bool IsConstructCall() const; inline Local<Value> Data() const; - inline Isolate* GetIsolate() const; - private: - static const int kIsolateIndex = 0; - static const int kDataIndex = -1; - static const int kCalleeIndex = -2; - static const int kHolderIndex = -3; + static const int kDataIndex = 0; + static const int kCalleeIndex = -1; + static const int kHolderIndex = -2; friend class ImplementationUtilities; inline Arguments(internal::Object** implicit_args, @@ -2001,11 +1993,9 @@ class V8EXPORT AccessorInfo { public: inline AccessorInfo(internal::Object** args) : args_(args) { } - inline Isolate* GetIsolate() const; inline Local<Value> Data() const; inline Local<Object> This() const; inline Local<Object> Holder() const; - private: internal::Object** args_; }; @@ -2562,11 +2552,6 @@ Handle<Primitive> V8EXPORT Null(); Handle<Boolean> V8EXPORT True(); Handle<Boolean> V8EXPORT False(); -inline Handle<Primitive> Undefined(Isolate* isolate); -inline Handle<Primitive> Null(Isolate* isolate); -inline Handle<Boolean> True(Isolate* isolate); -inline Handle<Boolean> False(Isolate* isolate); - /** * A set of constraints that specifies the limits of the runtime's memory use. @@ -2817,13 +2802,13 @@ class V8EXPORT Isolate { /** * Associate embedder-specific data with the isolate */ - inline void SetData(void* data); + void SetData(void* data); /** - * Retrieve embedder-specific data from the isolate. + * Retrive embedder-specific data from the isolate. * Returns NULL if SetData has never been called. */ - inline void* GetData(); + void* GetData(); private: Isolate(); @@ -3168,8 +3153,7 @@ class V8EXPORT V8 { * that is kept alive by JavaScript objects. * \returns the adjusted value. */ - static intptr_t AdjustAmountOfExternalAllocatedMemory( - intptr_t change_in_bytes); + static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes); /** * Suspends recording of tick samples in the profiler. @@ -3752,12 +3736,6 @@ class V8EXPORT Locker { /** - * A struct for exporting HeapStats data from V8, using "push" model. - */ -struct HeapStatsUpdate; - - -/** * An interface for exporting data from V8, using "push" model. */ class V8EXPORT OutputStream { // NOLINT @@ -3782,14 +3760,6 @@ class V8EXPORT OutputStream { // NOLINT * will not be called in case writing was aborted. */ virtual WriteResult WriteAsciiChunk(char* data, int size) = 0; - /** - * Writes the next chunk of heap stats data into the stream. Writing - * can be stopped by returning kAbort as function result. EndOfStream - * will not be called in case writing was aborted. - */ - virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) { - return kAbort; - }; }; @@ -3878,6 +3848,18 @@ const uintptr_t kEncodablePointerMask = PlatformSmiTagging::kEncodablePointerMask; const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift; +template <size_t ptr_size> struct InternalConstants; + +// Internal constants for 32-bit systems. +template <> struct InternalConstants<4> { + static const int kStringResourceOffset = 3 * kApiPointerSize; +}; + +// Internal constants for 64-bit systems. +template <> struct InternalConstants<8> { + static const int kStringResourceOffset = 3 * kApiPointerSize; +}; + /** * This class exports constants and functionality from within v8 that * is necessary to implement inline functions in the v8 api. Don't @@ -3889,31 +3871,18 @@ class Internals { // the implementation of v8. static const int kHeapObjectMapOffset = 0; static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize; - static const int kStringResourceOffset = 3 * kApiPointerSize; + static const int kStringResourceOffset = + InternalConstants<kApiPointerSize>::kStringResourceOffset; - static const int kOddballKindOffset = 3 * kApiPointerSize; static const int kForeignAddressOffset = kApiPointerSize; static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFullStringRepresentationMask = 0x07; static const int kExternalTwoByteRepresentationTag = 0x02; - static const int kIsolateStateOffset = 0; - static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize; - static const int kIsolateRootsOffset = 3 * kApiPointerSize; - static const int kUndefinedValueRootIndex = 5; - static const int kNullValueRootIndex = 7; - static const int kTrueValueRootIndex = 8; - static const int kFalseValueRootIndex = 9; - static const int kEmptySymbolRootIndex = 128; - static const int kJSObjectType = 0xaa; static const int kFirstNonstringType = 0x80; - static const int kOddballType = 0x82; static const int kForeignType = 0x85; - static const int kUndefinedOddballKind = 5; - static const int kNullOddballKind = 3; - static inline bool HasHeapObjectTag(internal::Object* value) { return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == kHeapObjectTag); @@ -3933,11 +3902,6 @@ class Internals { return ReadField<uint8_t>(map, kMapInstanceTypeOffset); } - static inline int GetOddballKind(internal::Object* obj) { - typedef internal::Object O; - return SmiValue(ReadField<O*>(obj, kOddballKindOffset)); - } - static inline void* GetExternalPointerFromSmi(internal::Object* value) { const uintptr_t address = reinterpret_cast<uintptr_t>(value); return reinterpret_cast<void*>(address >> kPointerToSmiShift); @@ -3958,28 +3922,6 @@ class Internals { return representation == kExternalTwoByteRepresentationTag; } - static inline bool IsInitialized(v8::Isolate* isolate) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateStateOffset; - return *reinterpret_cast<int*>(addr) == 1; - } - - static inline void SetEmbedderData(v8::Isolate* isolate, void* data) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + - kIsolateEmbedderDataOffset; - *reinterpret_cast<void**>(addr) = data; - } - - static inline void* GetEmbedderData(v8::Isolate* isolate) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + - kIsolateEmbedderDataOffset; - return *reinterpret_cast<void**>(addr); - } - - static inline internal::Object** GetRoot(v8::Isolate* isolate, int index) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateRootsOffset; - return reinterpret_cast<internal::Object**>(addr + index * kApiPointerSize); - } - template <typename T> static inline T ReadField(Object* ptr, int offset) { uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag; @@ -4106,11 +4048,6 @@ Local<Value> Arguments::Data() const { } -Isolate* Arguments::GetIsolate() const { - return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]); -} - - bool Arguments::IsConstructCall() const { return is_construct_call_; } @@ -4223,15 +4160,6 @@ String* String::Cast(v8::Value* value) { } -Local<String> String::Empty(Isolate* isolate) { - typedef internal::Object* S; - typedef internal::Internals I; - if (!I::IsInitialized(isolate)) return Empty(); - S* slot = I::GetRoot(isolate, I::kEmptySymbolRootIndex); - return Local<String>(reinterpret_cast<String*>(slot)); -} - - String::ExternalStringResource* String::GetExternalStringResource() const { typedef internal::Object O; typedef internal::Internals I; @@ -4250,42 +4178,6 @@ String::ExternalStringResource* String::GetExternalStringResource() const { } -bool Value::IsUndefined() const { -#ifdef V8_ENABLE_CHECKS - return FullIsUndefined(); -#else - return QuickIsUndefined(); -#endif -} - -bool Value::QuickIsUndefined() const { - typedef internal::Object O; - typedef internal::Internals I; - O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); - if (!I::HasHeapObjectTag(obj)) return false; - if (I::GetInstanceType(obj) != I::kOddballType) return false; - return (I::GetOddballKind(obj) == I::kUndefinedOddballKind); -} - - -bool Value::IsNull() const { -#ifdef V8_ENABLE_CHECKS - return FullIsNull(); -#else - return QuickIsNull(); -#endif -} - -bool Value::QuickIsNull() const { - typedef internal::Object O; - typedef internal::Internals I; - O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); - if (!I::HasHeapObjectTag(obj)) return false; - if (I::GetInstanceType(obj) != I::kOddballType) return false; - return (I::GetOddballKind(obj) == I::kNullOddballKind); -} - - bool Value::IsString() const { #ifdef V8_ENABLE_CHECKS return FullIsString(); @@ -4391,11 +4283,6 @@ External* External::Cast(v8::Value* value) { } -Isolate* AccessorInfo::GetIsolate() const { - return *reinterpret_cast<Isolate**>(&args_[-3]); -} - - Local<Value> AccessorInfo::Data() const { return Local<Value>(reinterpret_cast<Value*>(&args_[-2])); } @@ -4411,54 +4298,6 @@ Local<Object> AccessorInfo::Holder() const { } -Handle<Primitive> Undefined(Isolate* isolate) { - typedef internal::Object* S; - typedef internal::Internals I; - if (!I::IsInitialized(isolate)) return Undefined(); - S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex); - return Handle<Primitive>(reinterpret_cast<Primitive*>(slot)); -} - - -Handle<Primitive> Null(Isolate* isolate) { - typedef internal::Object* S; - typedef internal::Internals I; - if (!I::IsInitialized(isolate)) return Null(); - S* slot = I::GetRoot(isolate, I::kNullValueRootIndex); - return Handle<Primitive>(reinterpret_cast<Primitive*>(slot)); -} - - -Handle<Boolean> True(Isolate* isolate) { - typedef internal::Object* S; - typedef internal::Internals I; - if (!I::IsInitialized(isolate)) return True(); - S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex); - return Handle<Boolean>(reinterpret_cast<Boolean*>(slot)); -} - - -Handle<Boolean> False(Isolate* isolate) { - typedef internal::Object* S; - typedef internal::Internals I; - if (!I::IsInitialized(isolate)) return False(); - S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex); - return Handle<Boolean>(reinterpret_cast<Boolean*>(slot)); -} - - -void Isolate::SetData(void* data) { - typedef internal::Internals I; - I::SetEmbedderData(this, data); -} - - -void* Isolate::GetData() { - typedef internal::Internals I; - return I::GetEmbedderData(this); -} - - /** * \example shell.cc * A simple shell that takes a list of expressions on the diff --git a/deps/v8/samples/lineprocessor.cc b/deps/v8/samples/lineprocessor.cc index 7a84a2a0ff..1606a8f99c 100644 --- a/deps/v8/samples/lineprocessor.cc +++ b/deps/v8/samples/lineprocessor.cc @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2009 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -434,9 +434,9 @@ v8::Handle<v8::String> ReadLine() { } if (res == NULL) { v8::Handle<v8::Primitive> t = v8::Undefined(); - return v8::Handle<v8::String>(v8::String::Cast(*t)); + return reinterpret_cast<v8::Handle<v8::String>&>(t); } - // Remove newline char + // remove newline char for (char* pos = buffer; *pos != '\0'; pos++) { if (*pos == '\n') { *pos = '\0'; diff --git a/deps/v8/samples/samples.gyp b/deps/v8/samples/samples.gyp index 3c720a748a..55b2a98acd 100644 --- a/deps/v8/samples/samples.gyp +++ b/deps/v8/samples/samples.gyp @@ -1,4 +1,4 @@ -# Copyright 2012 the V8 project authors. All rights reserved. +# Copyright 2011 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: @@ -48,12 +48,6 @@ 'sources': [ 'process.cc', ], - }, - { - 'target_name': 'lineprocessor', - 'sources': [ - 'lineprocessor.cc', - ], } ], } diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc index db0cc1a930..b40eca2f7c 100644 --- a/deps/v8/samples/shell.cc +++ b/deps/v8/samples/shell.cc @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -67,20 +67,17 @@ static bool run_shell; int main(int argc, char* argv[]) { v8::V8::SetFlagsFromCommandLine(&argc, argv, true); run_shell = (argc == 1); - int result; - { - v8::HandleScope handle_scope; - v8::Persistent<v8::Context> context = CreateShellContext(); - if (context.IsEmpty()) { - printf("Error creating context\n"); - return 1; - } - context->Enter(); - result = RunMain(argc, argv); - if (run_shell) RunShell(context); - context->Exit(); - context.Dispose(); + v8::HandleScope handle_scope; + v8::Persistent<v8::Context> context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Error creating context\n"); + return 1; } + context->Enter(); + int result = RunMain(argc, argv); + if (run_shell) RunShell(context); + context->Exit(); + context.Dispose(); v8::V8::Dispose(); return result; } diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 0bc93c2ff2..4e731fbec8 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -512,16 +512,6 @@ void RegisteredExtension::Register(RegisteredExtension* that) { } -void RegisteredExtension::UnregisterAll() { - RegisteredExtension* re = first_extension_; - while (re != NULL) { - RegisteredExtension* next = re->next(); - delete re; - re = next; - } -} - - void RegisterExtension(Extension* that) { RegisteredExtension* extension = new RegisteredExtension(that); RegisteredExtension::Register(extension); @@ -2101,21 +2091,17 @@ bool StackFrame::IsConstructor() const { // --- D a t a --- -bool Value::FullIsUndefined() const { +bool Value::IsUndefined() const { if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) { return false; } - bool result = Utils::OpenHandle(this)->IsUndefined(); - ASSERT_EQ(result, QuickIsUndefined()); - return result; + return Utils::OpenHandle(this)->IsUndefined(); } -bool Value::FullIsNull() const { +bool Value::IsNull() const { if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false; - bool result = Utils::OpenHandle(this)->IsNull(); - ASSERT_EQ(result, QuickIsNull()); - return result; + return Utils::OpenHandle(this)->IsNull(); } @@ -2813,13 +2799,9 @@ bool v8::Object::ForceDelete(v8::Handle<Value> key) { i::Handle<i::JSObject> self = Utils::OpenHandle(this); i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); - // When deleting a property on the global object using ForceDelete - // deoptimize all functions as optimized code does not check for the hole - // value with DontDelete properties. We have to deoptimize all contexts - // because of possible cross-context inlined functions. - if (self->IsJSGlobalProxy() || self->IsGlobalObject()) { - i::Deoptimizer::DeoptimizeAll(); - } + // When turning on access checks for a global object deoptimize all functions + // as optimized code does not always handle access checks. + i::Deoptimizer::DeoptimizeGlobalObject(*self); EXCEPTION_PREAMBLE(isolate); i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj); @@ -4630,9 +4612,7 @@ void* External::Value() const { Local<String> v8::String::Empty() { i::Isolate* isolate = i::Isolate::Current(); - if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { - return v8::Local<String>(); - } + EnsureInitializedForIsolate(isolate, "v8::String::Empty()"); LOG_API(isolate, "String::Empty()"); return Utils::ToLocal(isolate->factory()->empty_symbol()); } @@ -5218,7 +5198,7 @@ void V8::AddImplicitReferences(Persistent<Object> parent, } -intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) { +int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) { i::Isolate* isolate = i::Isolate::Current(); if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) { return 0; @@ -5398,6 +5378,17 @@ void Isolate::Exit() { } +void Isolate::SetData(void* data) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + isolate->SetData(data); +} + +void* Isolate::GetData() { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + return isolate->GetData(); +} + + String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) : str_(NULL), length_(0) { i::Isolate* isolate = i::Isolate::Current(); @@ -5997,7 +5988,7 @@ Handle<Value> HeapGraphEdge::GetName() const { const HeapGraphNode* HeapGraphEdge::GetFromNode() const { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode"); - const i::HeapEntry* from = ToInternal(this)->from(); + const i::HeapEntry* from = ToInternal(this)->From(); return reinterpret_cast<const HeapGraphNode*>(from); } @@ -6031,7 +6022,7 @@ Handle<String> HeapGraphNode::GetName() const { } -SnapshotObjectId HeapGraphNode::GetId() const { +uint64_t HeapGraphNode::GetId() const { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapGraphNode::GetId"); return ToInternal(this)->id(); @@ -6146,11 +6137,11 @@ const HeapGraphNode* HeapSnapshot::GetRoot() const { } -const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const { +const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById"); return reinterpret_cast<const HeapGraphNode*>( - ToInternal(this)->GetEntryById(id)); + ToInternal(this)->GetEntryById(static_cast<i::SnapshotObjectId>(id))); } @@ -6169,13 +6160,6 @@ const HeapGraphNode* HeapSnapshot::GetNode(int index) const { } -SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const { - i::Isolate* isolate = i::Isolate::Current(); - IsDeadCheck(isolate, "v8::HeapSnapshot::GetMaxSnapshotJSObjectId"); - return ToInternal(this)->max_snapshot_js_object_id(); -} - - void HeapSnapshot::Serialize(OutputStream* stream, HeapSnapshot::SerializationFormat format) const { i::Isolate* isolate = i::Isolate::Current(); @@ -6217,14 +6201,6 @@ const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) { } -SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Value> value) { - i::Isolate* isolate = i::Isolate::Current(); - IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotObjectId"); - i::Handle<i::Object> obj = Utils::OpenHandle(*value); - return i::HeapProfiler::GetSnapshotObjectId(obj); -} - - const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title, HeapSnapshot::Type type, ActivityControl* control) { @@ -6244,27 +6220,6 @@ const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title, } -void HeapProfiler::StartHeapObjectsTracking() { - i::Isolate* isolate = i::Isolate::Current(); - IsDeadCheck(isolate, "v8::HeapProfiler::StartHeapObjectsTracking"); - i::HeapProfiler::StartHeapObjectsTracking(); -} - - -void HeapProfiler::StopHeapObjectsTracking() { - i::Isolate* isolate = i::Isolate::Current(); - IsDeadCheck(isolate, "v8::HeapProfiler::StopHeapObjectsTracking"); - i::HeapProfiler::StopHeapObjectsTracking(); -} - - -void HeapProfiler::PushHeapObjectsStats(OutputStream* stream) { - i::Isolate* isolate = i::Isolate::Current(); - IsDeadCheck(isolate, "v8::HeapProfiler::PushHeapObjectsStats"); - return i::HeapProfiler::PushHeapObjectsStats(stream); -} - - void HeapProfiler::DeleteAllSnapshots() { i::Isolate* isolate = i::Isolate::Current(); IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots"); @@ -6312,11 +6267,7 @@ static void SetFlagsFromString(const char* flags) { void Testing::PrepareStressRun(int run) { static const char* kLazyOptimizations = - "--prepare-always-opt " - "--max-inlined-source-size=999999 " - "--max-inlined-nodes=999999 " - "--max-inlined-nodes-cumulative=999999 " - "--noalways-opt"; + "--prepare-always-opt --nolimit-inlining --noalways-opt"; static const char* kForcedOptimizations = "--always-opt"; // If deoptimization stressed turn on frequent deoptimization. If no value diff --git a/deps/v8/src/api.h b/deps/v8/src/api.h index 3ad57f4657..89cf0c864c 100644 --- a/deps/v8/src/api.h +++ b/deps/v8/src/api.h @@ -146,7 +146,6 @@ class RegisteredExtension { public: explicit RegisteredExtension(Extension* extension); static void Register(RegisteredExtension* that); - static void UnregisterAll(); Extension* extension() { return extension_; } RegisteredExtension* next() { return next_; } RegisteredExtension* next_auto() { return next_auto_; } diff --git a/deps/v8/src/apiutils.h b/deps/v8/src/apiutils.h index 71c0e1c2c4..68579af1b3 100644 --- a/deps/v8/src/apiutils.h +++ b/deps/v8/src/apiutils.h @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2009 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -40,17 +40,14 @@ class ImplementationUtilities { } // Packs additional parameters for the NewArguments function. |implicit_args| - // is a pointer to the last element of 4-elements array controlled by GC. + // is a pointer to the last element of 3-elements array controlled by GC. static void PrepareArgumentsData(internal::Object** implicit_args, - internal::Isolate* isolate, internal::Object* data, internal::JSFunction* callee, internal::Object* holder) { implicit_args[v8::Arguments::kDataIndex] = data; implicit_args[v8::Arguments::kCalleeIndex] = callee; implicit_args[v8::Arguments::kHolderIndex] = holder; - implicit_args[v8::Arguments::kIsolateIndex] = - reinterpret_cast<internal::Object*>(isolate); } static v8::Arguments NewArguments(internal::Object** implicit_args, @@ -58,8 +55,6 @@ class ImplementationUtilities { bool is_construct_call) { ASSERT(implicit_args[v8::Arguments::kCalleeIndex]->IsJSFunction()); ASSERT(implicit_args[v8::Arguments::kHolderIndex]->IsHeapObject()); - // The implicit isolate argument is not tagged and looks like a SMI. - ASSERT(implicit_args[v8::Arguments::kIsolateIndex]->IsSmi()); return v8::Arguments(implicit_args, argv, argc, is_construct_call); } diff --git a/deps/v8/src/arguments.h b/deps/v8/src/arguments.h index f8fb00c575..e9a32702cf 100644 --- a/deps/v8/src/arguments.h +++ b/deps/v8/src/arguments.h @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2006-2008 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -91,11 +91,9 @@ class CustomArguments : public Relocatable { Object* data, Object* self, JSObject* holder) : Relocatable(isolate) { - ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi()); - values_[3] = self; - values_[2] = holder; - values_[1] = data; - values_[0] = reinterpret_cast<Object*>(isolate); + values_[2] = self; + values_[1] = holder; + values_[0] = data; } inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) { @@ -108,9 +106,8 @@ class CustomArguments : public Relocatable { void IterateInstance(ObjectVisitor* v); Object** end() { return values_ + ARRAY_SIZE(values_) - 1; } - private: - Object* values_[4]; + Object* values_[3]; }; diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index ad2ab7e09d..f772db9be2 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -5169,9 +5169,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); __ b(ne, &call); // Patch the receiver on the stack with the global receiver object. - __ ldr(r3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset)); - __ str(r3, MemOperand(sp, argc_ * kPointerSize)); + __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); + __ str(r2, MemOperand(sp, argc_ * kPointerSize)); __ bind(&call); } @@ -5179,13 +5179,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // r1: pushed function (to be verified) __ JumpIfSmi(r1, &non_function); // Get the map of the function object. - __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); + __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ b(ne, &slow); - if (RecordCallTarget()) { - GenerateRecordCallTarget(masm); - } - // Fast-case: Invoke the function now. // r1: pushed function ParameterCount actual(argc_); @@ -5209,17 +5205,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); - if (RecordCallTarget()) { - // If there is a call target cache, mark it megamorphic in the - // non-function case. MegamorphicSentinel is an immortal immovable - // object (undefined) so no write barrier is needed. - ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), - masm->isolate()->heap()->undefined_value()); - __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - __ str(ip, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset)); - } // Check for function proxy. - __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); + __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE)); __ b(ne, &non_function); __ push(r1); // put proxy as additional argument __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE)); @@ -5886,12 +5873,36 @@ void SubStringStub::Generate(MacroAssembler* masm) { // r2: result string length __ ldr(r4, FieldMemOperand(r0, String::kLengthOffset)); __ cmp(r2, Operand(r4, ASR, 1)); - // Return original string. __ b(eq, &return_r0); - // Longer than original string's length or negative: unsafe arguments. - __ b(hi, &runtime); - // Shorter than original string's length: an actual substring. + Label result_longer_than_two; + // Check for special case of two character ASCII string, in which case + // we do a lookup in the symbol table first. + __ cmp(r2, Operand(2)); + __ b(gt, &result_longer_than_two); + __ b(lt, &runtime); + + __ JumpIfInstanceTypeIsNotSequentialAscii(r1, r1, &runtime); + + // Get the two characters forming the sub string. + __ add(r0, r0, Operand(r3)); + __ ldrb(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); + __ ldrb(r4, FieldMemOperand(r0, SeqAsciiString::kHeaderSize + 1)); + + // Try to lookup two character string in symbol table. + Label make_two_character_string; + StringHelper::GenerateTwoCharacterSymbolTableProbe( + masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string); + __ jmp(&return_r0); + + // r2: result string length. + // r3: two characters combined into halfword in little endian byte order. + __ bind(&make_two_character_string); + __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime); + __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); + __ jmp(&return_r0); + + __ bind(&result_longer_than_two); // Deal with different string types: update the index if necessary // and put the underlying string into r5. // r0: original string diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index 3c8df292c4..69b12ce5ee 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -112,6 +112,13 @@ class JumpPatchSite BASE_EMBEDDED { }; +// TODO(jkummerow): Obsolete as soon as x64 is updated. Remove. +int FullCodeGenerator::self_optimization_header_size() { + UNREACHABLE(); + return 24; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right. The actual // argument count matches the formal parameter count expected by the @@ -268,11 +275,11 @@ void FullCodeGenerator::Generate() { // For named function expressions, declare the function name as a // constant. if (scope()->is_function_scope() && scope()->function() != NULL) { - VariableDeclaration* function = scope()->function(); - ASSERT(function->proxy()->var()->mode() == CONST || - function->proxy()->var()->mode() == CONST_HARMONY); - ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); - VisitVariableDeclaration(function); + VariableProxy* proxy = scope()->function(); + ASSERT(proxy->var()->mode() == CONST || + proxy->var()->mode() == CONST_HARMONY); + ASSERT(proxy->var()->location() != Variable::UNALLOCATED); + EmitDeclaration(proxy, proxy->var()->mode(), NULL); } VisitDeclarations(scope()->declarations()); } @@ -782,51 +789,62 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, } -void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { - // The variable in the declaration always resides in the current function - // context. - ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); - if (FLAG_debug_code) { - // Check that we're not inside a with or catch context. - __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset)); - __ CompareRoot(r1, Heap::kWithContextMapRootIndex); - __ Check(ne, "Declaration in with context."); - __ CompareRoot(r1, Heap::kCatchContextMapRootIndex); - __ Check(ne, "Declaration in catch context."); - } -} - - -void FullCodeGenerator::VisitVariableDeclaration( - VariableDeclaration* declaration) { +void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function) { // If it was not possible to allocate the variable at compile time, we // need to "declare" it at runtime to make sure it actually exists in the // local context. - VariableProxy* proxy = declaration->proxy(); - VariableMode mode = declaration->mode(); Variable* variable = proxy->var(); - bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; + bool binding_needs_init = (function == NULL) && + (mode == CONST || mode == CONST_HARMONY || mode == LET); switch (variable->location()) { case Variable::UNALLOCATED: - globals_->Add(variable->name()); - globals_->Add(variable->binding_needs_init() - ? isolate()->factory()->the_hole_value() - : isolate()->factory()->undefined_value()); + ++global_count_; break; case Variable::PARAMETER: case Variable::LOCAL: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ str(result_register(), StackOperand(variable)); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ str(ip, StackOperand(variable)); } break; case Variable::CONTEXT: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); - EmitDebugCheckDeclarationContext(variable); + // The variable in the decl always resides in the current function + // context. + ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); + if (FLAG_debug_code) { + // Check that we're not inside a with or catch context. + __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset)); + __ CompareRoot(r1, Heap::kWithContextMapRootIndex); + __ Check(ne, "Declaration in with context."); + __ CompareRoot(r1, Heap::kCatchContextMapRootIndex); + __ Check(ne, "Declaration in catch context."); + } + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ str(result_register(), ContextOperand(cp, variable->index())); + int offset = Context::SlotOffset(variable->index()); + // We know that we have written a function, which is not a smi. + __ RecordWriteContextSlot(cp, + offset, + result_register(), + r2, + kLRHasBeenSaved, + kDontSaveFPRegs, + EMIT_REMEMBERED_SET, + OMIT_SMI_CHECK); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ str(ip, ContextOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. @@ -835,11 +853,13 @@ void FullCodeGenerator::VisitVariableDeclaration( break; case Variable::LOOKUP: { - Comment cmnt(masm_, "[ VariableDeclaration"); + Comment cmnt(masm_, "[ Declaration"); __ mov(r2, Operand(variable->name())); // Declaration nodes are always introduced in one of four modes. - ASSERT(mode == VAR || mode == LET || - mode == CONST || mode == CONST_HARMONY); + ASSERT(mode == VAR || + mode == CONST || + mode == CONST_HARMONY || + mode == LET); PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE; __ mov(r1, Operand(Smi::FromInt(attr))); @@ -847,7 +867,11 @@ void FullCodeGenerator::VisitVariableDeclaration( // Note: For variables we must not push an initial value (such as // 'undefined') because we may have a (legal) redeclaration and we // must not destroy the current value. - if (hole_init) { + if (function != NULL) { + __ Push(cp, r2, r1); + // Push initial value for function declaration. + VisitForStackValue(function); + } else if (binding_needs_init) { __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); __ Push(cp, r2, r1, r0); } else { @@ -861,122 +885,6 @@ void FullCodeGenerator::VisitVariableDeclaration( } -void FullCodeGenerator::VisitFunctionDeclaration( - FunctionDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: { - globals_->Add(variable->name()); - Handle<SharedFunctionInfo> function = - Compiler::BuildFunctionInfo(declaration->fun(), script()); - // Check for stack-overflow exception. - if (function.is_null()) return SetStackOverflow(); - globals_->Add(function); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - VisitForAccumulatorValue(declaration->fun()); - __ str(result_register(), StackOperand(variable)); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - EmitDebugCheckDeclarationContext(variable); - VisitForAccumulatorValue(declaration->fun()); - __ str(result_register(), ContextOperand(cp, variable->index())); - int offset = Context::SlotOffset(variable->index()); - // We know that we have written a function, which is not a smi. - __ RecordWriteContextSlot(cp, - offset, - result_register(), - r2, - kLRHasBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), NO_REGISTERS); - break; - } - - case Variable::LOOKUP: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - __ mov(r2, Operand(variable->name())); - __ mov(r1, Operand(Smi::FromInt(NONE))); - __ Push(cp, r2, r1); - // Push initial value for function declaration. - VisitForStackValue(declaration->fun()); - __ CallRuntime(Runtime::kDeclareContextSlot, 4); - break; - } - } -} - - -void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - Handle<JSModule> instance = declaration->module()->interface()->Instance(); - ASSERT(!instance.is_null()); - - switch (variable->location()) { - case Variable::UNALLOCATED: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - globals_->Add(variable->name()); - globals_->Add(instance); - Visit(declaration->module()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - EmitDebugCheckDeclarationContext(variable); - __ mov(r1, Operand(instance)); - __ str(r1, ContextOperand(cp, variable->index())); - Visit(declaration->module()); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: - // TODO(rossberg) - break; - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ImportDeclaration"); - EmitDebugCheckDeclarationContext(variable); - // TODO(rossberg) - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { - // TODO(rossberg) -} - - void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { // Call the runtime to declare the globals. // The context is the first argument. @@ -2363,18 +2271,6 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - - // Record call targets in unoptimized code, but not in the snapshot. - if (!Serializer::enabled()) { - flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); - Handle<Object> uninitialized = - TypeFeedbackCells::UninitializedSentinel(isolate()); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); - RecordTypeFeedbackCell(expr->id(), cell); - __ mov(r2, Operand(cell)); - } - CallFunctionStub stub(arg_count, flags); __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); __ CallStub(&stub); @@ -3668,7 +3564,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); __ ldr(scratch1, FieldMemOperand(string, SeqAsciiString::kLengthOffset)); - __ add(string_length, string_length, Operand(scratch1), SetCC); + __ add(string_length, string_length, Operand(scratch1)); __ b(vs, &bailout); __ cmp(element, elements_end); __ b(lt, &loop); @@ -3705,7 +3601,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { __ b(ne, &bailout); __ tst(scratch2, Operand(0x80000000)); __ b(ne, &bailout); - __ add(string_length, string_length, Operand(scratch2), SetCC); + __ add(string_length, string_length, Operand(scratch2)); __ b(vs, &bailout); __ SmiUntag(string_length); @@ -4461,8 +4357,7 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) { void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { Scope* declaration_scope = scope()->DeclarationScope(); - if (declaration_scope->is_global_scope() || - declaration_scope->is_module_scope()) { + if (declaration_scope->is_global_scope()) { // Contexts nested in the global context have a canonical empty function // as their closure, not the anonymous closure containing the global // code. Pass a smi sentinel and let the runtime look up the empty diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index 5c60f5321c..c3dd1cbaa2 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -108,17 +108,22 @@ void LInstruction::PrintTo(StringStream* stream) { } -void LInstruction::PrintDataTo(StringStream* stream) { +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { stream->Add("= "); - for (int i = 0; i < InputCount(); i++) { + for (int i = 0; i < inputs_.length(); i++) { if (i > 0) stream->Add(" "); - InputAt(i)->PrintTo(stream); + inputs_[i]->PrintTo(stream); } } -void LInstruction::PrintOutputOperandTo(StringStream* stream) { - if (HasResult()) result()->PrintTo(stream); +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { + for (int i = 0; i < results_.length(); i++) { + if (i > 0) stream->Add(" "); + results_[i]->PrintTo(stream); + } } @@ -727,6 +732,22 @@ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { } +LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id) { + ASSERT(instruction_pending_deoptimization_environment_ == NULL); + ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); + instruction_pending_deoptimization_environment_ = instr; + pending_deoptimization_ast_id_ = ast_id; + return instr; +} + + +void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { + instruction_pending_deoptimization_environment_ = NULL; + pending_deoptimization_ast_id_ = AstNode::kNoNumber; +} + + LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize) { @@ -739,10 +760,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, if (hinstr->HasObservableSideEffects()) { ASSERT(hinstr->next()->IsSimulate()); HSimulate* sim = HSimulate::cast(hinstr->next()); - ASSERT(instruction_pending_deoptimization_environment_ == NULL); - ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); - instruction_pending_deoptimization_environment_ = instr; - pending_deoptimization_ast_id_ = sim->ast_id(); + instr = SetInstructionPendingDeoptimizationEnvironment( + instr, sim->ast_id()); } // If instruction does not have side-effects lazy deoptimization @@ -760,6 +779,12 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, } +LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { + instr->MarkAsSaveDoubles(); + return instr; +} + + LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { ASSERT(!instr->HasPointerMap()); instr->set_pointer_map(new(zone()) LPointerMap(position_)); @@ -1270,7 +1295,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; LOperand* value = UseRegisterAtStart(instr->value()); return DefineAsRegister(new(zone()) LBitNotI(value)); } @@ -1295,75 +1319,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { } -bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) { - uint32_t divisor_abs = abs(divisor); - // Dividing by 0, 1, and powers of 2 is easy. - // Note that IsPowerOf2(0) returns true; - ASSERT(IsPowerOf2(0) == true); - if (IsPowerOf2(divisor_abs)) return true; - - // We have magic numbers for a few specific divisors. - // Details and proofs can be found in: - // - Hacker's Delight, Henry S. Warren, Jr. - // - The PowerPC Compiler Writer’s Guide - // and probably many others. - // - // We handle - // <divisor with magic numbers> * <power of 2> - // but not - // <divisor with magic numbers> * <other divisor with magic numbers> - int32_t power_of_2_factor = - CompilerIntrinsics::CountTrailingZeros(divisor_abs); - DivMagicNumbers magic_numbers = - DivMagicNumberFor(divisor_abs >> power_of_2_factor); - if (magic_numbers.M != InvalidDivMagicNumber.M) return true; - - return false; -} - - -HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { - // A value with an integer representation does not need to be transformed. - if (dividend->representation().IsInteger32()) { - return dividend; - // A change from an integer32 can be replaced by the integer32 value. - } else if (dividend->IsChange() && - HChange::cast(dividend)->from().IsInteger32()) { - return HChange::cast(dividend)->value(); - } - return NULL; -} - - -HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { - // Only optimize when we have magic numbers for the divisor. - // The standard integer division routine is usually slower than transitionning - // to VFP. - if (divisor->IsConstant() && - HConstant::cast(divisor)->HasInteger32Value()) { - HConstant* constant_val = HConstant::cast(divisor); - int32_t int32_val = constant_val->Integer32Value(); - if (LChunkBuilder::HasMagicNumberForDivisor(int32_val)) { - return constant_val->CopyToRepresentation(Representation::Integer32()); - } - } - return NULL; -} - - -LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { - HValue* right = instr->right(); - LOperand* dividend = UseRegister(instr->left()); - LOperand* divisor = UseRegisterOrConstant(right); - LOperand* remainder = TempRegister(); - ASSERT(right->IsConstant() && - HConstant::cast(right)->HasInteger32Value() && - HasMagicNumberForDivisor(HConstant::cast(right)->Integer32Value())); - return AssignEnvironment(DefineAsRegister( - new LMathFloorOfDiv(dividend, divisor, remainder))); -} - - LInstruction* LChunkBuilder::DoMod(HMod* instr) { if (instr->representation().IsInteger32()) { ASSERT(instr->left()->representation().IsInteger32()); @@ -1798,9 +1753,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { } -LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { +LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - LInstruction* result = new(zone()) LCheckMaps(value); + LInstruction* result = new(zone()) LCheckMap(value); return AssignEnvironment(result); } @@ -2287,12 +2242,9 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { if (pending_deoptimization_ast_id_ == instr->ast_id()) { LInstruction* result = new(zone()) LLazyBailout; result = AssignEnvironment(result); - // Store the lazy deopt environment with the instruction if needed. Right - // now it is only used for LInstanceOfKnownGlobal. instruction_pending_deoptimization_environment_-> - SetDeferredLazyDeoptimizationEnvironment(result->environment()); - instruction_pending_deoptimization_environment_ = NULL; - pending_deoptimization_ast_id_ = AstNode::kNoNumber; + set_deoptimization_environment(result->environment()); + ClearInstructionPendingDeoptimizationEnvironment(); return result; } @@ -2319,8 +2271,8 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { undefined, instr->call_kind(), instr->is_construct()); - if (instr->arguments_var() != NULL) { - inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject()); + if (instr->arguments() != NULL) { + inner->Bind(instr->arguments(), graph()->GetArgumentsObject()); } current_block_->UpdateEnvironment(inner); chunk_->AddInlinedClosure(instr->closure()); @@ -2329,21 +2281,10 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { - LInstruction* pop = NULL; - - HEnvironment* env = current_block_->last_environment(); - - if (instr->arguments_pushed()) { - int argument_count = env->arguments_environment()->parameter_count(); - pop = new(zone()) LDrop(argument_count); - argument_count_ -= argument_count; - } - HEnvironment* outer = current_block_->last_environment()-> DiscardInlined(false); current_block_->UpdateEnvironment(outer); - - return pop; + return NULL; } diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h index ec8aac8036..62cde6e249 100644 --- a/deps/v8/src/arm/lithium-arm.h +++ b/deps/v8/src/arm/lithium-arm.h @@ -72,7 +72,7 @@ class LCodeGen; V(CheckFunction) \ V(CheckInstanceType) \ V(CheckNonSmi) \ - V(CheckMaps) \ + V(CheckMap) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ V(ClampDToUint8) \ @@ -132,7 +132,6 @@ class LCodeGen; V(LoadNamedField) \ V(LoadNamedFieldPolymorphic) \ V(LoadNamedGeneric) \ - V(MathFloorOfDiv) \ V(ModI) \ V(MulI) \ V(NumberTagD) \ @@ -180,8 +179,7 @@ class LCodeGen; V(CheckMapValue) \ V(LoadFieldByIndex) \ V(DateField) \ - V(WrapReceiver) \ - V(Drop) + V(WrapReceiver) #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ @@ -205,14 +203,15 @@ class LInstruction: public ZoneObject { LInstruction() : environment_(NULL), hydrogen_value_(NULL), - is_call_(false) { } + is_call_(false), + is_save_doubles_(false) { } virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; virtual const char* Mnemonic() const = 0; virtual void PrintTo(StringStream* stream); - virtual void PrintDataTo(StringStream* stream); - virtual void PrintOutputOperandTo(StringStream* stream); + virtual void PrintDataTo(StringStream* stream) = 0; + virtual void PrintOutputOperandTo(StringStream* stream) = 0; enum Opcode { // Declare a unique enum value for each instruction. @@ -247,12 +246,22 @@ class LInstruction: public ZoneObject { void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } + void set_deoptimization_environment(LEnvironment* env) { + deoptimization_environment_.set(env); + } + LEnvironment* deoptimization_environment() const { + return deoptimization_environment_.get(); + } + bool HasDeoptimizationEnvironment() const { + return deoptimization_environment_.is_set(); + } void MarkAsCall() { is_call_ = true; } + void MarkAsSaveDoubles() { is_save_doubles_ = true; } // Interface to the register allocator and iterators. bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; } virtual bool HasResult() const = 0; virtual LOperand* result() = 0; @@ -273,7 +282,9 @@ class LInstruction: public ZoneObject { LEnvironment* environment_; SetOncePointer<LPointerMap> pointer_map_; HValue* hydrogen_value_; + SetOncePointer<LEnvironment> deoptimization_environment_; bool is_call_; + bool is_save_doubles_; }; @@ -295,6 +306,9 @@ class LTemplateInstruction: public LInstruction { int TempCount() { return T; } LOperand* TempAt(int i) { return temps_[i]; } + virtual void PrintDataTo(StringStream* stream); + virtual void PrintOutputOperandTo(StringStream* stream); + protected: EmbeddedContainer<LOperand*, R> results_; EmbeddedContainer<LOperand*, I> inputs_; @@ -520,8 +534,9 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { public: + LArgumentsElements() { } + DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") - DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) }; @@ -567,21 +582,6 @@ class LDivI: public LTemplateInstruction<1, 2, 0> { }; -class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> { - public: - LMathFloorOfDiv(LOperand* left, - LOperand* right, - LOperand* temp = NULL) { - inputs_[0] = left; - inputs_[1] = right; - temps_[0] = temp; - } - - DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div") - DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) -}; - - class LMulI: public LTemplateInstruction<1, 2, 1> { public: LMulI(LOperand* left, LOperand* right, LOperand* temp) { @@ -834,15 +834,6 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) Handle<JSFunction> function() const { return hydrogen()->function(); } - LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { - return lazy_deopt_env_; - } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { - lazy_deopt_env_ = env; - } - - private: - LEnvironment* lazy_deopt_env_; }; @@ -1387,19 +1378,6 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; -class LDrop: public LTemplateInstruction<0, 0, 0> { - public: - explicit LDrop(int count) : count_(count) { } - - int count() const { return count_; } - - DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") - - private: - int count_; -}; - - class LThisFunction: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") @@ -1482,7 +1460,6 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { virtual void PrintDataTo(StringStream* stream); int arity() const { return hydrogen()->argument_count() - 1; } - Handle<JSFunction> known_function() { return hydrogen()->known_function(); } }; @@ -1762,8 +1739,6 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - - bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; @@ -1914,14 +1889,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> { }; -class LCheckMaps: public LTemplateInstruction<0, 1, 0> { +class LCheckMap: public LTemplateInstruction<0, 1, 0> { public: - explicit LCheckMaps(LOperand* value) { + explicit LCheckMap(LOperand* value) { inputs_[0] = value; } - DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") - DECLARE_HYDROGEN_ACCESSOR(CheckMaps) + DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") + DECLARE_HYDROGEN_ACCESSOR(CheckMap) }; @@ -2299,10 +2274,6 @@ class LChunkBuilder BASE_EMBEDDED { HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) #undef DECLARE_DO - static bool HasMagicNumberForDivisor(int32_t divisor); - static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val); - static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val); - private: enum Status { UNUSED, @@ -2398,6 +2369,11 @@ class LChunkBuilder BASE_EMBEDDED { LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); + LInstruction* MarkAsSaveDoubles(LInstruction* instr); + + LInstruction* SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id); + void ClearInstructionPendingDeoptimizationEnvironment(); LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, int* argument_index_accumulator); diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc index 79b56fc077..82b80a2b80 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.cc +++ b/deps/v8/src/arm/lithium-codegen-arm.cc @@ -1034,100 +1034,6 @@ void LCodeGen::DoModI(LModI* instr) { } -void LCodeGen::EmitSignedIntegerDivisionByConstant( - Register result, - Register dividend, - int32_t divisor, - Register remainder, - Register scratch, - LEnvironment* environment) { - ASSERT(!AreAliased(dividend, scratch, ip)); - ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor)); - - uint32_t divisor_abs = abs(divisor); - - int32_t power_of_2_factor = - CompilerIntrinsics::CountTrailingZeros(divisor_abs); - - switch (divisor_abs) { - case 0: - DeoptimizeIf(al, environment); - return; - - case 1: - if (divisor > 0) { - __ Move(result, dividend); - } else { - __ rsb(result, dividend, Operand(0), SetCC); - DeoptimizeIf(vs, environment); - } - // Compute the remainder. - __ mov(remainder, Operand(0)); - return; - - default: - if (IsPowerOf2(divisor_abs)) { - // Branch and condition free code for integer division by a power - // of two. - int32_t power = WhichPowerOf2(divisor_abs); - if (power > 1) { - __ mov(scratch, Operand(dividend, ASR, power - 1)); - } - __ add(scratch, dividend, Operand(scratch, LSR, 32 - power)); - __ mov(result, Operand(scratch, ASR, power)); - // Negate if necessary. - // We don't need to check for overflow because the case '-1' is - // handled separately. - if (divisor < 0) { - ASSERT(divisor != -1); - __ rsb(result, result, Operand(0)); - } - // Compute the remainder. - if (divisor > 0) { - __ sub(remainder, dividend, Operand(result, LSL, power)); - } else { - __ add(remainder, dividend, Operand(result, LSL, power)); - } - return; - } else { - // Use magic numbers for a few specific divisors. - // Details and proofs can be found in: - // - Hacker's Delight, Henry S. Warren, Jr. - // - The PowerPC Compiler Writer’s Guide - // and probably many others. - // - // We handle - // <divisor with magic numbers> * <power of 2> - // but not - // <divisor with magic numbers> * <other divisor with magic numbers> - DivMagicNumbers magic_numbers = - DivMagicNumberFor(divisor_abs >> power_of_2_factor); - // Branch and condition free code for integer division by a power - // of two. - const int32_t M = magic_numbers.M; - const int32_t s = magic_numbers.s + power_of_2_factor; - - __ mov(ip, Operand(M)); - __ smull(ip, scratch, dividend, ip); - if (M < 0) { - __ add(scratch, scratch, Operand(dividend)); - } - if (s > 0) { - __ mov(scratch, Operand(scratch, ASR, s)); - } - __ add(result, scratch, Operand(dividend, LSR, 31)); - if (divisor < 0) __ rsb(result, result, Operand(0)); - // Compute the remainder. - __ mov(ip, Operand(divisor)); - // This sequence could be replaced with 'mls' when - // it gets implemented. - __ mul(scratch, result, ip); - __ sub(remainder, dividend, scratch); - } - } -} - - void LCodeGen::DoDivI(LDivI* instr) { class DeferredDivI: public LDeferredCode { public: @@ -1209,34 +1115,6 @@ void LCodeGen::DoDivI(LDivI* instr) { } -void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { - const Register result = ToRegister(instr->result()); - const Register left = ToRegister(instr->InputAt(0)); - const Register remainder = ToRegister(instr->TempAt(0)); - const Register scratch = scratch0(); - - // We only optimize this for division by constants, because the standard - // integer division routine is usually slower than transitionning to VFP. - // This could be optimized on processors with SDIV available. - ASSERT(instr->InputAt(1)->IsConstantOperand()); - int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); - if (divisor < 0) { - __ cmp(left, Operand(0)); - DeoptimizeIf(eq, instr->environment()); - } - EmitSignedIntegerDivisionByConstant(result, - left, - divisor, - remainder, - scratch, - instr->environment()); - // We operated a truncating division. Correct the result if necessary. - __ cmp(remainder, Operand(0)); - __ teq(remainder, Operand(divisor), ne); - __ sub(result, result, Operand(1), LeaveCC, mi); -} - - template<int T> void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr, Token::Value op) { @@ -2389,7 +2267,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RelocInfo::CODE_TARGET, instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Put the result value into the result register slot and // restore all registers. @@ -2885,20 +2764,16 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register scratch = scratch0(); Register result = ToRegister(instr->result()); - if (instr->hydrogen()->from_inlined()) { - __ sub(result, sp, Operand(2 * kPointerSize)); - } else { - // Check if the calling frame is an arguments adaptor frame. - Label done, adapted; - __ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); - __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + // Check if the calling frame is an arguments adaptor frame. + Label done, adapted; + __ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); + __ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); + __ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ mov(result, fp, LeaveCC, ne); - __ mov(result, scratch, LeaveCC, eq); - } + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ mov(result, fp, LeaveCC, ne); + __ mov(result, scratch, LeaveCC, eq); } @@ -3007,7 +2882,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { __ b(ne, &loop); __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -3032,11 +2907,6 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } -void LCodeGen::DoDrop(LDrop* instr) { - __ Drop(instr->count()); -} - - void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); @@ -3083,8 +2953,7 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - R1State r1_state) { + CallKind call_kind) { bool can_invoke_directly = !function->NeedsArgumentsAdaption() || function->shared()->formal_parameter_count() == arity; @@ -3092,10 +2961,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, RecordPosition(pointers->position()); if (can_invoke_directly) { - if (r1_state == R1_UNINITIALIZED) { - __ LoadHeapObject(r1, function); - } - + __ LoadHeapObject(r1, function); // Change context if needed. bool change_context = (info()->closure()->context() != function->context()) || @@ -3134,8 +3000,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { CallKnownFunction(instr->function(), instr->arity(), instr, - CALL_AS_METHOD, - R1_UNINITIALIZED); + CALL_AS_METHOD); } @@ -3559,21 +3424,13 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->function()).is(r1)); ASSERT(instr->HasPointerMap()); - - if (instr->known_function().is_null()) { - LPointerMap* pointers = instr->pointer_map(); - RecordPosition(pointers->position()); - SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); - ParameterCount count(instr->arity()); - __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); - __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - } else { - CallKnownFunction(instr->known_function(), - instr->arity(), - instr, - CALL_AS_METHOD, - R1_CONTAINS_TARGET); - } + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + RecordPosition(pointers->position()); + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); + ParameterCount count(instr->arity()); + __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); + __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } @@ -3628,11 +3485,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(r0)); - CallKnownFunction(instr->target(), - instr->arity(), - instr, - CALL_AS_FUNCTION, - R1_UNINITIALIZED); + CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); } @@ -3762,6 +3615,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Register scratch = scratch0(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; + Label not_nan; // Calculate the effective address of the slot in the array to store the // double value. @@ -3784,15 +3638,13 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); } - if (instr->NeedsCanonicalization()) { - // Check for NaN. All NaNs must be canonicalized. - __ VFPCompareAndSetFlags(value, value); - // Only load canonical NaN if the comparison above set the overflow. - __ Vmov(value, - FixedDoubleArray::canonical_not_the_hole_nan_as_double(), - vs); - } + // Check for NaN. All NaNs must be canonicalized. + __ VFPCompareAndSetFlags(value, value); + + // Only load canonical NaN if the comparison above set the overflow. + __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs); + __ bind(¬_nan); __ vstr(value, scratch, 0); } @@ -4486,22 +4338,14 @@ void LCodeGen::DoCheckMapCommon(Register reg, } -void LCodeGen::DoCheckMaps(LCheckMaps* instr) { +void LCodeGen::DoCheckMap(LCheckMap* instr) { Register scratch = scratch0(); LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); - - Label success; - SmallMapList* map_set = instr->hydrogen()->map_set(); - for (int i = 0; i < map_set->length() - 1; i++) { - Handle<Map> map = map_set->at(i); - __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); - __ b(eq, &success); - } - Handle<Map> map = map_set->last(); - DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); - __ bind(&success); + Handle<Map> map = instr->hydrogen()->map(); + DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(), + instr->environment()); } @@ -4620,14 +4464,6 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { deferred->entry(), TAG_OBJECT); - __ bind(deferred->exit()); - if (FLAG_debug_code) { - Label is_in_new_space; - __ JumpIfInNewSpace(result, scratch, &is_in_new_space); - __ Abort("Allocated object is not in new-space"); - __ bind(&is_in_new_space); - } - // Load the initial map. Register map = scratch; __ LoadHeapObject(map, constructor); @@ -4646,14 +4482,14 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { __ str(scratch, FieldMemOperand(result, property_offset)); } } + + __ bind(deferred->exit()); } void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); - int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the // result register contain a valid pointer because it is already @@ -4661,9 +4497,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { __ mov(result, Operand(0)); PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - __ mov(r0, Operand(Smi::FromInt(instance_size))); + __ LoadHeapObject(r0, constructor); __ push(r0); - CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); + CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr); __ StoreToSafepointRegisterSlot(r0, result); } @@ -4797,10 +4633,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ str(r2, FieldMemOperand(result, total_offset + 4)); } } else if (elements->IsFixedArray()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); for (int i = 0; i < elements_length; i++) { int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(object, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); __ add(r2, result, Operand(*offset)); @@ -4824,23 +4659,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, void LCodeGen::DoFastLiteral(LFastLiteral* instr) { int size = instr->hydrogen()->total_size(); - ElementsKind boilerplate_elements_kind = - instr->hydrogen()->boilerplate()->GetElementsKind(); - - // Deopt if the literal boilerplate ElementsKind is of a type different than - // the expected one. The check isn't necessary if the boilerplate has already - // been converted to FAST_ELEMENTS. - if (boilerplate_elements_kind != FAST_ELEMENTS) { - __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); - // Load map into r2. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - // Load the map's "bit field 2". - __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); - // Retrieve elements_kind from bit field 2. - __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); - __ cmp(r2, Operand(boilerplate_elements_kind)); - DeoptimizeIf(ne, instr->environment()); - } // Allocate all objects that are part of the literal in one big // allocation. This avoids multiple limit checks. @@ -5136,7 +4954,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { Register strict = scratch0(); __ mov(strict, Operand(Smi::FromInt(strict_mode_flag()))); __ Push(object, key, strict); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -5149,7 +4967,7 @@ void LCodeGen::DoIn(LIn* instr) { Register obj = ToRegister(instr->object()); Register key = ToRegister(instr->key()); __ Push(key, obj); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h index c6a3af7e02..adb6e1bb73 100644 --- a/deps/v8/src/arm/lithium-codegen-arm.h +++ b/deps/v8/src/arm/lithium-codegen-arm.h @@ -215,18 +215,12 @@ class LCodeGen BASE_EMBEDDED { int argc, LInstruction* instr); - enum R1State { - R1_UNINITIALIZED, - R1_CONTAINS_TARGET - }; - // Generate a direct call to a known function. Expects the function // to be in r1. void CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - R1State r1_state); + CallKind call_kind); void LoadHeapObject(Register result, Handle<HeapObject> object); @@ -323,17 +317,6 @@ class LCodeGen BASE_EMBEDDED { Register source, int* offset); - // Emit optimized code for integer division. - // Inputs are signed. - // All registers are clobbered. - // If 'remainder' is no_reg, it is not computed. - void EmitSignedIntegerDivisionByConstant(Register result, - Register dividend, - int32_t divisor, - Register remainder, - Register scratch, - LEnvironment* environment); - struct JumpTableEntry { explicit inline JumpTableEntry(Address entry) : label(), diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 42c9961b3e..857c2bf770 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -3710,28 +3710,15 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { } -#ifdef DEBUG -bool AreAliased(Register reg1, - Register reg2, - Register reg3, - Register reg4, - Register reg5, - Register reg6) { - int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + - reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid(); - - RegList regs = 0; - if (reg1.is_valid()) regs |= reg1.bit(); - if (reg2.is_valid()) regs |= reg2.bit(); - if (reg3.is_valid()) regs |= reg3.bit(); - if (reg4.is_valid()) regs |= reg4.bit(); - if (reg5.is_valid()) regs |= reg5.bit(); - if (reg6.is_valid()) regs |= reg6.bit(); - int n_of_non_aliasing_regs = NumRegs(regs); - - return n_of_valid_regs != n_of_non_aliasing_regs; +bool AreAliased(Register r1, Register r2, Register r3, Register r4) { + if (r1.is(r2)) return true; + if (r1.is(r3)) return true; + if (r1.is(r4)) return true; + if (r2.is(r3)) return true; + if (r2.is(r4)) return true; + if (r3.is(r4)) return true; + return false; } -#endif CodePatcher::CodePatcher(byte* address, int instructions) diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index 360f4c128c..47afa93a6e 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -85,14 +85,7 @@ enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved }; -#ifdef DEBUG -bool AreAliased(Register reg1, - Register reg2, - Register reg3 = no_reg, - Register reg4 = no_reg, - Register reg5 = no_reg, - Register reg6 = no_reg); -#endif +bool AreAliased(Register r1, Register r2, Register r3, Register r4); // MacroAssembler implements a collection of frequently used macros. @@ -1328,6 +1321,7 @@ class MacroAssembler: public Assembler { }; +#ifdef ENABLE_DEBUGGER_SUPPORT // The code patcher is used to patch (typically) small parts of code e.g. for // debugging and other types of instrumentation. When using the code patcher // the exact number of bytes specified must be emitted. It is not legal to emit @@ -1357,6 +1351,7 @@ class CodePatcher { int size_; // Number of bytes of the expected patch size. MacroAssembler masm_; // Macro assembler used to generate the code. }; +#endif // ENABLE_DEBUGGER_SUPPORT // ----------------------------------------------------------------------------- diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.cc b/deps/v8/src/arm/regexp-macro-assembler-arm.cc index a833624ceb..10ff2dd96c 100644 --- a/deps/v8/src/arm/regexp-macro-assembler-arm.cc +++ b/deps/v8/src/arm/regexp-macro-assembler-arm.cc @@ -452,12 +452,8 @@ void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, void RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_equal) { - if (c == 0) { - __ tst(current_character(), Operand(mask)); - } else { - __ and_(r0, current_character(), Operand(mask)); - __ cmp(r0, Operand(c)); - } + __ and_(r0, current_character(), Operand(mask)); + __ cmp(r0, Operand(c)); BranchOrBacktrack(eq, on_equal); } @@ -465,12 +461,8 @@ void RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c, void RegExpMacroAssemblerARM::CheckNotCharacterAfterAnd(unsigned c, unsigned mask, Label* on_not_equal) { - if (c == 0) { - __ tst(current_character(), Operand(mask)); - } else { - __ and_(r0, current_character(), Operand(mask)); - __ cmp(r0, Operand(c)); - } + __ and_(r0, current_character(), Operand(mask)); + __ cmp(r0, Operand(c)); BranchOrBacktrack(ne, on_not_equal); } @@ -488,44 +480,6 @@ void RegExpMacroAssemblerARM::CheckNotCharacterAfterMinusAnd( } -void RegExpMacroAssemblerARM::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - __ sub(r0, current_character(), Operand(from)); - __ cmp(r0, Operand(to - from)); - BranchOrBacktrack(ls, on_in_range); // Unsigned lower-or-same condition. -} - - -void RegExpMacroAssemblerARM::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - __ sub(r0, current_character(), Operand(from)); - __ cmp(r0, Operand(to - from)); - BranchOrBacktrack(hi, on_not_in_range); // Unsigned higher condition. -} - - -void RegExpMacroAssemblerARM::CheckBitInTable( - Handle<ByteArray> table, - Label* on_bit_set) { - __ mov(r0, Operand(table)); - if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { - __ and_(r1, current_character(), Operand(kTableSize - 1)); - __ add(r1, r1, Operand(ByteArray::kHeaderSize - kHeapObjectTag)); - } else { - __ add(r1, - current_character(), - Operand(ByteArray::kHeaderSize - kHeapObjectTag)); - } - __ ldrb(r0, MemOperand(r0, r1)); - __ cmp(r0, Operand(0)); - BranchOrBacktrack(ne, on_bit_set); -} - - bool RegExpMacroAssemblerARM::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { // Range checks (c in min..max) are generally implemented by an unsigned diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.h b/deps/v8/src/arm/regexp-macro-assembler-arm.h index 14f984f567..5c8ed0693f 100644 --- a/deps/v8/src/arm/regexp-macro-assembler-arm.h +++ b/deps/v8/src/arm/regexp-macro-assembler-arm.h @@ -79,14 +79,6 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler { uc16 minus, uc16 mask, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); - // Checks whether the given offset from the current position is before // the end of the string. virtual void CheckPosition(int cp_offset, Label* on_outside_input); diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc index 49c0982301..d514b607ae 100644 --- a/deps/v8/src/arm/stub-cache-arm.cc +++ b/deps/v8/src/arm/stub-cache-arm.cc @@ -582,8 +582,6 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(holder); __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); __ push(scratch); - __ mov(scratch, Operand(ExternalReference::isolate_address())); - __ push(scratch); } @@ -598,7 +596,7 @@ static void CompileCallLoadPropertyWithInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()); - __ mov(r0, Operand(6)); + __ mov(r0, Operand(5)); __ mov(r1, Operand(ref)); CEntryStub stub(1); @@ -606,9 +604,9 @@ static void CompileCallLoadPropertyWithInterceptor( } -static const int kFastApiCallArguments = 4; +static const int kFastApiCallArguments = 3; -// Reserves space for the extra arguments to API function in the +// Reserves space for the extra arguments to FastHandleApiCall in the // caller's frame. // // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. @@ -634,8 +632,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // -- sp[0] : holder (set by CheckPrototypes) // -- sp[4] : callee JS function // -- sp[8] : call data - // -- sp[12] : isolate - // -- sp[16] : last JS argument + // -- sp[12] : last JS argument // -- ... // -- sp[(argc + 3) * 4] : first JS argument // -- sp[(argc + 4) * 4] : receiver @@ -645,7 +642,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, __ LoadHeapObject(r5, function); __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); - // Pass the additional arguments. + // Pass the additional arguments FastHandleApiCall expects. Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); Handle<Object> call_data(api_call_info->data()); if (masm->isolate()->heap()->InNewSpace(*call_data)) { @@ -654,15 +651,13 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, } else { __ Move(r6, call_data); } - __ mov(r7, Operand(ExternalReference::isolate_address())); - // Store JS function, call data and isolate. - __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit()); + // Store JS function and call data. + __ stm(ib, sp, r5.bit() | r6.bit()); - // Prepare arguments. - __ add(r2, sp, Operand(3 * kPointerSize)); + // r2 points to call data as expected by Arguments + // (refer to layout above). + __ add(r2, sp, Operand(2 * kPointerSize)); - // Allocate the v8::Arguments structure in the arguments' space since - // it's not controlled by GC. const int kApiStackSpace = 4; FrameScope frame_scope(masm, StackFrame::MANUAL); @@ -671,9 +666,9 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // r0 = v8::Arguments& // Arguments is after the return address. __ add(r0, sp, Operand(1 * kPointerSize)); - // v8::Arguments::implicit_args_ + // v8::Arguments::implicit_args = data __ str(r2, MemOperand(r0, 0 * kPointerSize)); - // v8::Arguments::values_ + // v8::Arguments::values = last argument __ add(ip, r2, Operand(argc * kPointerSize)); __ str(ip, MemOperand(r0, 1 * kPointerSize)); // v8::Arguments::length_ = argc @@ -850,7 +845,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 6); + 5); // Restore the name_ register. __ pop(name_); // Leave the internal frame. @@ -1209,9 +1204,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, } else { __ Move(scratch3, Handle<Object>(callback->data())); } - __ Push(reg, scratch3); - __ mov(scratch3, Operand(ExternalReference::isolate_address())); - __ Push(scratch3, name_reg); + __ Push(reg, scratch3, name_reg); __ mov(r0, sp); // r0 = Handle<String> const int kApiStackSpace = 1; @@ -1223,7 +1216,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, __ str(scratch2, MemOperand(sp, 1 * kPointerSize)); __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& - const int kStackUnwindSpace = 5; + const int kStackUnwindSpace = 4; Address getter_address = v8::ToCData<Address>(callback->getter()); ApiFunction fun(getter_address); ExternalReference ref = @@ -1351,19 +1344,20 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, if (!receiver.is(holder_reg)) { ASSERT(scratch1.is(holder_reg)); __ Push(receiver, holder_reg); + __ ldr(scratch3, + FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); + __ Push(scratch3, scratch2, name_reg); } else { __ push(receiver); - __ push(holder_reg); + __ ldr(scratch3, + FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); + __ Push(holder_reg, scratch3, scratch2, name_reg); } - __ ldr(scratch3, - FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); - __ mov(scratch1, Operand(ExternalReference::isolate_address())); - __ Push(scratch3, scratch1, scratch2, name_reg); ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), masm()->isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1377,7 +1371,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } @@ -1745,7 +1739,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall( // We can't address the last element in one operation. Compute the more // expensive shift first, and use an offset later on. __ add(elements, elements, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize)); - __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); + __ ldr(r0, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); __ cmp(r0, r6); __ b(eq, &call_builtin); @@ -1753,7 +1747,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall( __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); // Fill with the hole. - __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); + __ str(r6, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); __ Drop(argc + 1); __ Ret(); @@ -3383,44 +3377,6 @@ static bool IsElementTypeSigned(ElementsKind elements_kind) { } -static void GenerateSmiKeyCheck(MacroAssembler* masm, - Register key, - Register scratch0, - Register scratch1, - DwVfpRegister double_scratch0, - Label* fail) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); - Label key_ok; - // Check for smi or a smi inside a heap number. We convert the heap - // number and check if the conversion is exact and fits into the smi - // range. - __ JumpIfSmi(key, &key_ok); - __ CheckMap(key, - scratch0, - Heap::kHeapNumberMapRootIndex, - fail, - DONT_DO_SMI_CHECK); - __ sub(ip, key, Operand(kHeapObjectTag)); - __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); - __ EmitVFPTruncate(kRoundToZero, - double_scratch0.low(), - double_scratch0, - scratch0, - scratch1, - kCheckForInexactConversion); - __ b(ne, fail); - __ vmov(scratch0, double_scratch0.low()); - __ TrySmiTag(scratch0, fail, scratch1); - __ mov(key, scratch0); - __ bind(&key_ok); - } else { - // Check that the key is a smi. - __ JumpIfNotSmi(key, fail); - } -} - - void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, ElementsKind elements_kind) { @@ -3437,8 +3393,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key, &miss_force_generic); __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); // r3: elements array @@ -3768,8 +3724,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key, &miss_force_generic); __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); @@ -4094,8 +4050,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, r0, r4, r5, d1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(r0, &miss_force_generic); // Get the elements array. __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset)); @@ -4146,8 +4102,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key_reg, &miss_force_generic); // Get the elements array. __ ldr(elements_reg, @@ -4222,8 +4178,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key_reg, &miss_force_generic); if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { __ JumpIfNotSmi(value_reg, &transition_elements_kind); @@ -4389,9 +4345,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic); + __ JumpIfNotSmi(key_reg, &miss_force_generic); __ ldr(elements_reg, FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); diff --git a/deps/v8/src/array.js b/deps/v8/src/array.js index a1cc5b6a7d..00a4fee5cd 100644 --- a/deps/v8/src/array.js +++ b/deps/v8/src/array.js @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2010 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: @@ -465,19 +465,15 @@ function ArrayPush() { } -// Returns an array containing the array elements of the object followed -// by the array elements of each argument in order. See ECMA-262, -// section 15.4.4.7. function ArrayConcat(arg1) { // length == 1 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { throw MakeTypeError("called_on_null_or_undefined", ["Array.prototype.concat"]); } - var array = ToObject(this); var arg_count = %_ArgumentsLength(); var arrays = new InternalArray(1 + arg_count); - arrays[0] = array; + arrays[0] = this; for (var i = 0; i < arg_count; i++) { arrays[i + 1] = %_Arguments(i); } @@ -1031,28 +1027,13 @@ function ArrayFilter(f, receiver) { var result = new $Array(); var accumulator = new InternalArray(); var accumulator_length = 0; - if (%DebugCallbackSupportsStepping(f)) { - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(f); - if (%_CallFunction(receiver, element, i, array, f)) { - accumulator[accumulator_length++] = element; - } - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - if (%_CallFunction(receiver, element, i, array, f)) { - accumulator[accumulator_length++] = element; - } + for (var i = 0; i < length; i++) { + if (i in array) { + var element = array[i]; + if (%_CallFunction(receiver, element, i, array, f)) { + accumulator[accumulator_length++] = element; } } - // End of duplicate. } %MoveArrayContents(accumulator, result); return result; @@ -1078,24 +1059,12 @@ function ArrayForEach(f, receiver) { } else if (!IS_SPEC_OBJECT(receiver)) { receiver = ToObject(receiver); } - if (%DebugCallbackSupportsStepping(f)) { - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(f); - %_CallFunction(receiver, element, i, array, f); - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - %_CallFunction(receiver, element, i, array, f); - } + + for (var i = 0; i < length; i++) { + if (i in array) { + var element = array[i]; + %_CallFunction(receiver, element, i, array, f); } - // End of duplicate. } } @@ -1122,24 +1091,11 @@ function ArraySome(f, receiver) { receiver = ToObject(receiver); } - if (%DebugCallbackSupportsStepping(f)) { - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(f); - if (%_CallFunction(receiver, element, i, array, f)) return true; - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - if (%_CallFunction(receiver, element, i, array, f)) return true; - } + for (var i = 0; i < length; i++) { + if (i in array) { + var element = array[i]; + if (%_CallFunction(receiver, element, i, array, f)) return true; } - // End of duplicate. } return false; } @@ -1165,24 +1121,11 @@ function ArrayEvery(f, receiver) { receiver = ToObject(receiver); } - if (%DebugCallbackSupportsStepping(f)) { - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(f); - if (!%_CallFunction(receiver, element, i, array, f)) return false; - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - if (!%_CallFunction(receiver, element, i, array, f)) return false; - } + for (var i = 0; i < length; i++) { + if (i in array) { + var element = array[i]; + if (!%_CallFunction(receiver, element, i, array, f)) return false; } - // End of duplicate. } return true; } @@ -1209,24 +1152,11 @@ function ArrayMap(f, receiver) { var result = new $Array(); var accumulator = new InternalArray(length); - if (%DebugCallbackSupportsStepping(f)) { - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(f); - accumulator[i] = %_CallFunction(receiver, element, i, array, f); - } + for (var i = 0; i < length; i++) { + if (i in array) { + var element = array[i]; + accumulator[i] = %_CallFunction(receiver, element, i, array, f); } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (var i = 0; i < length; i++) { - if (i in array) { - var element = array[i]; - accumulator[i] = %_CallFunction(receiver, element, i, array, f); - } - } - // End of duplicate. } %MoveArrayContents(accumulator, result); return result; @@ -1381,27 +1311,11 @@ function ArrayReduce(callback, current) { } var receiver = %GetDefaultReceiver(callback); - - if (%DebugCallbackSupportsStepping(callback)) { - for (; i < length; i++) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(callback); - current = - %_CallFunction(receiver, current, element, i, array, callback); - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (; i < length; i++) { - if (i in array) { - var element = array[i]; - current = - %_CallFunction(receiver, current, element, i, array, callback); - } + for (; i < length; i++) { + if (i in array) { + var element = array[i]; + current = %_CallFunction(receiver, current, element, i, array, callback); } - // End of duplicate. } return current; } @@ -1434,27 +1348,11 @@ function ArrayReduceRight(callback, current) { } var receiver = %GetDefaultReceiver(callback); - - if (%DebugCallbackSupportsStepping(callback)) { - for (; i >= 0; i--) { - if (i in array) { - var element = array[i]; - // Prepare break slots for debugger step in. - %DebugPrepareStepInIfStepping(callback); - current = - %_CallFunction(receiver, current, element, i, array, callback); - } - } - } else { - // This is a duplicate of the previous loop sans debug stepping. - for (; i >= 0; i--) { - if (i in array) { - var element = array[i]; - current = - %_CallFunction(receiver, current, element, i, array, callback); - } + for (; i >= 0; i--) { + if (i in array) { + var element = array[i]; + current = %_CallFunction(receiver, current, element, i, array, callback); } - // End of duplicate. } return current; } diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc index be2564960d..4944202f07 100644 --- a/deps/v8/src/assembler.cc +++ b/deps/v8/src/assembler.cc @@ -99,7 +99,21 @@ struct DoubleConstant BASE_EMBEDDED { double the_hole_nan; }; -static DoubleConstant double_constants; +struct InitializeDoubleConstants { + static void Construct(DoubleConstant* double_constants) { + double_constants->min_int = kMinInt; + double_constants->one_half = 0.5; + double_constants->minus_zero = -0.0; + double_constants->uint8_max_value = 255; + double_constants->zero = 0.0; + double_constants->canonical_non_hole_nan = OS::nan_value(); + double_constants->the_hole_nan = BitCast<double>(kHoleNanInt64); + double_constants->negative_infinity = -V8_INFINITY; + } +}; + +static LazyInstance<DoubleConstant, InitializeDoubleConstants>::type + double_constants = LAZY_INSTANCE_INITIALIZER; const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING"; @@ -712,18 +726,6 @@ void RelocInfo::Verify() { // ----------------------------------------------------------------------------- // Implementation of ExternalReference -void ExternalReference::SetUp() { - double_constants.min_int = kMinInt; - double_constants.one_half = 0.5; - double_constants.minus_zero = -0.0; - double_constants.uint8_max_value = 255; - double_constants.zero = 0.0; - double_constants.canonical_non_hole_nan = OS::nan_value(); - double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64); - double_constants.negative_infinity = -V8_INFINITY; -} - - ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate) : address_(Redirect(isolate, Builtins::c_function_address(id))) {} @@ -956,47 +958,50 @@ ExternalReference ExternalReference::scheduled_exception_address( ExternalReference ExternalReference::address_of_min_int() { - return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->min_int)); } ExternalReference ExternalReference::address_of_one_half() { - return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->one_half)); } ExternalReference ExternalReference::address_of_minus_zero() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.minus_zero)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->minus_zero)); } ExternalReference ExternalReference::address_of_zero() { - return ExternalReference(reinterpret_cast<void*>(&double_constants.zero)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->zero)); } ExternalReference ExternalReference::address_of_uint8_max_value() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.uint8_max_value)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->uint8_max_value)); } ExternalReference ExternalReference::address_of_negative_infinity() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.negative_infinity)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->negative_infinity)); } ExternalReference ExternalReference::address_of_canonical_non_hole_nan() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->canonical_non_hole_nan)); } ExternalReference ExternalReference::address_of_the_hole_nan() { - return ExternalReference( - reinterpret_cast<void*>(&double_constants.the_hole_nan)); + return ExternalReference(reinterpret_cast<void*>( + &double_constants.Pointer()->the_hole_nan)); } @@ -1153,20 +1158,6 @@ double power_double_int(double x, int y) { double power_double_double(double x, double y) { -#ifdef __MINGW64_VERSION_MAJOR - // MinGW64 has a custom implementation for pow. This handles certain - // special cases that are different. - if ((x == 0.0 || isinf(x)) && isfinite(y)) { - double f; - if (modf(y, &f) != 0.0) return ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0; - } - - if (x == 2.0) { - int y_int = static_cast<int>(y); - if (y == y_int) return ldexp(1.0, y_int); - } -#endif - // The checks for special cases can be dropped in ia32 because it has already // been done in generated code before bailing out here. if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) return OS::nan_value(); diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h index 05fe320ad0..f960b58691 100644 --- a/deps/v8/src/assembler.h +++ b/deps/v8/src/assembler.h @@ -539,8 +539,6 @@ class ExternalReference BASE_EMBEDDED { DIRECT_GETTER_CALL }; - static void SetUp(); - typedef void* ExternalReferenceRedirector(void* original, Type type); ExternalReference(Builtins::CFunctionId id, Isolate* isolate); diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc index 6f9fd7afb2..4b6ae680a4 100644 --- a/deps/v8/src/ast.cc +++ b/deps/v8/src/ast.cc @@ -962,14 +962,6 @@ RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives) } -static int IncreaseBy(int previous, int increase) { - if (RegExpTree::kInfinity - previous < increase) { - return RegExpTree::kInfinity; - } else { - return previous + increase; - } -} - RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes) : nodes_(nodes) { ASSERT(nodes->length() > 1); @@ -977,10 +969,13 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes) max_match_ = 0; for (int i = 0; i < nodes->length(); i++) { RegExpTree* node = nodes->at(i); - int node_min_match = node->min_match(); - min_match_ = IncreaseBy(min_match_, node_min_match); + min_match_ += node->min_match(); int node_max_match = node->max_match(); - max_match_ = IncreaseBy(max_match_, node_max_match); + if (kInfinity - max_match_ < node_max_match) { + max_match_ = kInfinity; + } else { + max_match_ += node->max_match(); + } } } @@ -998,78 +993,138 @@ CaseClause::CaseClause(Isolate* isolate, } -#define REGULAR_NODE(NodeType) \ - void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ - increase_node_count(); \ - } -#define DONT_OPTIMIZE_NODE(NodeType) \ +#define INCREASE_NODE_COUNT(NodeType) \ void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ increase_node_count(); \ - add_flag(kDontOptimize); \ - add_flag(kDontInline); \ - add_flag(kDontSelfOptimize); \ - } -#define DONT_INLINE_NODE(NodeType) \ - void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ - increase_node_count(); \ - add_flag(kDontInline); \ - } -#define DONT_SELFOPTIMIZE_NODE(NodeType) \ - void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ - increase_node_count(); \ - add_flag(kDontSelfOptimize); \ } -REGULAR_NODE(VariableDeclaration) -REGULAR_NODE(FunctionDeclaration) -REGULAR_NODE(Block) -REGULAR_NODE(ExpressionStatement) -REGULAR_NODE(EmptyStatement) -REGULAR_NODE(IfStatement) -REGULAR_NODE(ContinueStatement) -REGULAR_NODE(BreakStatement) -REGULAR_NODE(ReturnStatement) -REGULAR_NODE(SwitchStatement) -REGULAR_NODE(Conditional) -REGULAR_NODE(Literal) -REGULAR_NODE(ObjectLiteral) -REGULAR_NODE(Assignment) -REGULAR_NODE(Throw) -REGULAR_NODE(Property) -REGULAR_NODE(UnaryOperation) -REGULAR_NODE(CountOperation) -REGULAR_NODE(BinaryOperation) -REGULAR_NODE(CompareOperation) -REGULAR_NODE(ThisFunction) -REGULAR_NODE(Call) -REGULAR_NODE(CallNew) -// In theory, for VariableProxy we'd have to add: -// if (node->var()->IsLookupSlot()) add_flag(kDontInline); -// But node->var() is usually not bound yet at VariableProxy creation time, and -// LOOKUP variables only result from constructs that cannot be inlined anyway. -REGULAR_NODE(VariableProxy) - -DONT_OPTIMIZE_NODE(ModuleDeclaration) -DONT_OPTIMIZE_NODE(ImportDeclaration) -DONT_OPTIMIZE_NODE(ExportDeclaration) -DONT_OPTIMIZE_NODE(ModuleLiteral) -DONT_OPTIMIZE_NODE(ModuleVariable) -DONT_OPTIMIZE_NODE(ModulePath) -DONT_OPTIMIZE_NODE(ModuleUrl) -DONT_OPTIMIZE_NODE(WithStatement) -DONT_OPTIMIZE_NODE(TryCatchStatement) -DONT_OPTIMIZE_NODE(TryFinallyStatement) -DONT_OPTIMIZE_NODE(DebuggerStatement) -DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral) - -DONT_INLINE_NODE(FunctionLiteral) -DONT_INLINE_NODE(RegExpLiteral) // TODO(1322): Allow materialized literals. -DONT_INLINE_NODE(ArrayLiteral) // TODO(1322): Allow materialized literals. - -DONT_SELFOPTIMIZE_NODE(DoWhileStatement) -DONT_SELFOPTIMIZE_NODE(WhileStatement) -DONT_SELFOPTIMIZE_NODE(ForStatement) -DONT_SELFOPTIMIZE_NODE(ForInStatement) +INCREASE_NODE_COUNT(VariableDeclaration) +INCREASE_NODE_COUNT(FunctionDeclaration) +INCREASE_NODE_COUNT(ModuleDeclaration) +INCREASE_NODE_COUNT(ImportDeclaration) +INCREASE_NODE_COUNT(ExportDeclaration) +INCREASE_NODE_COUNT(ModuleLiteral) +INCREASE_NODE_COUNT(ModuleVariable) +INCREASE_NODE_COUNT(ModulePath) +INCREASE_NODE_COUNT(ModuleUrl) +INCREASE_NODE_COUNT(Block) +INCREASE_NODE_COUNT(ExpressionStatement) +INCREASE_NODE_COUNT(EmptyStatement) +INCREASE_NODE_COUNT(IfStatement) +INCREASE_NODE_COUNT(ContinueStatement) +INCREASE_NODE_COUNT(BreakStatement) +INCREASE_NODE_COUNT(ReturnStatement) +INCREASE_NODE_COUNT(Conditional) +INCREASE_NODE_COUNT(Literal) +INCREASE_NODE_COUNT(ObjectLiteral) +INCREASE_NODE_COUNT(Assignment) +INCREASE_NODE_COUNT(Throw) +INCREASE_NODE_COUNT(Property) +INCREASE_NODE_COUNT(UnaryOperation) +INCREASE_NODE_COUNT(CountOperation) +INCREASE_NODE_COUNT(BinaryOperation) +INCREASE_NODE_COUNT(CompareOperation) +INCREASE_NODE_COUNT(ThisFunction) +INCREASE_NODE_COUNT(Call) +INCREASE_NODE_COUNT(CallNew) + +#undef INCREASE_NODE_COUNT + + +void AstConstructionVisitor::VisitWithStatement(WithStatement* node) { + increase_node_count(); + add_flag(kDontOptimize); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) { + increase_node_count(); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) { + increase_node_count(); + add_flag(kDontSelfOptimize); +} + + +void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) { + increase_node_count(); + add_flag(kDontSelfOptimize); +} + + +void AstConstructionVisitor::VisitForStatement(ForStatement* node) { + increase_node_count(); + add_flag(kDontSelfOptimize); +} + + +void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) { + increase_node_count(); + add_flag(kDontSelfOptimize); +} + + +void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) { + increase_node_count(); + add_flag(kDontOptimize); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitTryFinallyStatement( + TryFinallyStatement* node) { + increase_node_count(); + add_flag(kDontOptimize); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) { + increase_node_count(); + add_flag(kDontOptimize); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) { + increase_node_count(); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitSharedFunctionInfoLiteral( + SharedFunctionInfoLiteral* node) { + increase_node_count(); + add_flag(kDontOptimize); + add_flag(kDontInline); +} + + +void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) { + increase_node_count(); + // In theory, we'd have to add: + // if(node->var()->IsLookupSlot()) { add_flag(kDontInline); } + // However, node->var() is usually not bound yet at VariableProxy creation + // time, and LOOKUP variables only result from constructs that cannot + // be inlined anyway. +} + + +void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) { + increase_node_count(); + add_flag(kDontInline); // TODO(1322): Allow materialized literals. +} + + +void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) { + increase_node_count(); + add_flag(kDontInline); // TODO(1322): Allow materialized literals. +} + void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { increase_node_count(); @@ -1087,11 +1142,6 @@ void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { } } -#undef REGULAR_NODE -#undef DONT_OPTIMIZE_NODE -#undef DONT_INLINE_NODE -#undef DONT_SELFOPTIMIZE_NODE - Handle<String> Literal::ToString() { if (handle_->IsString()) return Handle<String>::cast(handle_); diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index dad80576bd..b827302ebd 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -270,7 +270,6 @@ class SmallMapList { void Reserve(int capacity) { list_.Reserve(capacity); } void Clear() { list_.Clear(); } - void Sort() { list_.Sort(); } bool is_empty() const { return list_.is_empty(); } int length() const { return list_.length(); } @@ -421,8 +420,8 @@ class Block: public BreakableStatement { ZoneList<Statement*>* statements() { return &statements_; } bool is_initializer_block() const { return is_initializer_block_; } - Scope* scope() const { return scope_; } - void set_scope(Scope* scope) { scope_ = scope; } + Scope* block_scope() const { return block_scope_; } + void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; } protected: template<class> friend class AstNodeFactory; @@ -434,13 +433,13 @@ class Block: public BreakableStatement { : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY), statements_(capacity), is_initializer_block_(is_initializer_block), - scope_(NULL) { + block_scope_(NULL) { } private: ZoneList<Statement*> statements_; bool is_initializer_block_; - Scope* scope_; + Scope* block_scope_; }; @@ -608,7 +607,6 @@ class ModuleLiteral: public Module { DECLARE_NODE_TYPE(ModuleLiteral) Block* body() const { return body_; } - Handle<Context> context() const { return context_; } protected: template<class> friend class AstNodeFactory; @@ -620,7 +618,6 @@ class ModuleLiteral: public Module { private: Block* body_; - Handle<Context> context_; }; diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index c65c68c2d7..0e95b4b839 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -1011,7 +1011,7 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, proto_map->set_prototype(global_context()->initial_object_prototype()); Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map); proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, - heap->query_colon_symbol()); + heap->empty_string()); proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, heap->false_value()); proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, @@ -2159,7 +2159,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, Handle<DescriptorArray> descs = Handle<DescriptorArray>(from->map()->instance_descriptors()); for (int i = 0; i < descs->number_of_descriptors(); i++) { - PropertyDetails details = descs->GetDetails(i); + PropertyDetails details = PropertyDetails(descs->GetDetails(i)); switch (details.type()) { case FIELD: { HandleScope inner; diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc index 84a0c3d19c..01e88f5593 100644 --- a/deps/v8/src/builtins.cc +++ b/deps/v8/src/builtins.cc @@ -1103,7 +1103,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( CustomArguments custom(isolate); v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), - isolate, data_obj, *function, raw_holder); + data_obj, *function, raw_holder); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( custom.end(), @@ -1143,6 +1143,68 @@ BUILTIN(HandleApiCallConstruct) { } +#ifdef DEBUG + +static void VerifyTypeCheck(Handle<JSObject> object, + Handle<JSFunction> function) { + ASSERT(function->shared()->IsApiFunction()); + FunctionTemplateInfo* info = function->shared()->get_api_func_data(); + if (info->signature()->IsUndefined()) return; + SignatureInfo* signature = SignatureInfo::cast(info->signature()); + Object* receiver_type = signature->receiver(); + if (receiver_type->IsUndefined()) return; + FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type); + ASSERT(object->IsInstanceOf(type)); +} + +#endif + + +BUILTIN(FastHandleApiCall) { + ASSERT(!CalledAsConstructor(isolate)); + Heap* heap = isolate->heap(); + const bool is_construct = false; + + // We expect four more arguments: callback, function, call data, and holder. + const int args_length = args.length() - 4; + ASSERT(args_length >= 0); + + Object* callback_obj = args[args_length]; + + v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( + &args[args_length + 1], + &args[0] - 1, + args_length - 1, + is_construct); + +#ifdef DEBUG + VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()), + Utils::OpenHandle(*new_args.Callee())); +#endif + HandleScope scope(isolate); + Object* result; + v8::Handle<v8::Value> value; + { + // Leaving JavaScript. + VMState state(isolate, EXTERNAL); + ExternalCallbackScope call_scope(isolate, + v8::ToCData<Address>(callback_obj)); + v8::InvocationCallback callback = + v8::ToCData<v8::InvocationCallback>(callback_obj); + + value = callback(new_args); + } + if (value.IsEmpty()) { + result = heap->undefined_value(); + } else { + result = *reinterpret_cast<Object**>(*value); + } + + RETURN_IF_SCHEDULED_EXCEPTION(isolate); + return result; +} + + // Helper function to handle calls to non-function objects created through the // API. The object can be called as either a constructor (using new) or just as // a function (without new). @@ -1181,7 +1243,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor( CustomArguments custom(isolate); v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), - isolate, call_data->data(), constructor, obj); + call_data->data(), constructor, obj); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( custom.end(), &args[0] - 1, diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h index 3ea33938eb..f079139d45 100644 --- a/deps/v8/src/builtins.h +++ b/deps/v8/src/builtins.h @@ -56,6 +56,7 @@ enum BuiltinExtraArguments { V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ \ V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ + V(FastHandleApiCall, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ diff --git a/deps/v8/src/bytecodes-irregexp.h b/deps/v8/src/bytecodes-irregexp.h index c7cc66e527..b13efb36f8 100644 --- a/deps/v8/src/bytecodes-irregexp.h +++ b/deps/v8/src/bytecodes-irregexp.h @@ -72,23 +72,24 @@ V(AND_CHECK_4_CHARS, 27, 16) /* bc8 pad24 uint32 uint32 addr32 */ \ V(AND_CHECK_CHAR, 28, 12) /* bc8 pad8 uint16 uint32 addr32 */ \ V(AND_CHECK_NOT_4_CHARS, 29, 16) /* bc8 pad24 uint32 uint32 addr32 */ \ V(AND_CHECK_NOT_CHAR, 30, 12) /* bc8 pad8 uint16 uint32 addr32 */ \ -V(MINUS_AND_CHECK_NOT_CHAR, 31, 12) /* bc8 pad8 uc16 uc16 uc16 addr32 */ \ -V(CHECK_CHAR_IN_RANGE, 32, 12) /* bc8 pad24 uc16 uc16 addr32 */ \ -V(CHECK_CHAR_NOT_IN_RANGE, 33, 12) /* bc8 pad24 uc16 uc16 addr32 */ \ -V(CHECK_BIT_IN_TABLE, 34, 24) /* bc8 pad24 addr32 bits128 */ \ -V(CHECK_LT, 35, 8) /* bc8 pad8 uc16 addr32 */ \ -V(CHECK_GT, 36, 8) /* bc8 pad8 uc16 addr32 */ \ -V(CHECK_NOT_BACK_REF, 37, 8) /* bc8 reg_idx24 addr32 */ \ -V(CHECK_NOT_BACK_REF_NO_CASE, 38, 8) /* bc8 reg_idx24 addr32 */ \ -V(CHECK_NOT_REGS_EQUAL, 39, 12) /* bc8 regidx24 reg_idx32 addr32 */ \ -V(CHECK_REGISTER_LT, 40, 12) /* bc8 reg_idx24 value32 addr32 */ \ -V(CHECK_REGISTER_GE, 41, 12) /* bc8 reg_idx24 value32 addr32 */ \ -V(CHECK_REGISTER_EQ_POS, 42, 8) /* bc8 reg_idx24 addr32 */ \ -V(CHECK_AT_START, 43, 8) /* bc8 pad24 addr32 */ \ -V(CHECK_NOT_AT_START, 44, 8) /* bc8 pad24 addr32 */ \ -V(CHECK_GREEDY, 45, 8) /* bc8 pad24 addr32 */ \ -V(ADVANCE_CP_AND_GOTO, 46, 8) /* bc8 offset24 addr32 */ \ -V(SET_CURRENT_POSITION_FROM_END, 47, 4) /* bc8 idx24 */ +V(MINUS_AND_CHECK_NOT_CHAR, 31, 12) /* bc8 pad8 uc16 uc16 addr32 */ \ +V(CHECK_LT, 32, 8) /* bc8 pad8 uc16 addr32 */ \ +V(CHECK_GT, 33, 8) /* bc8 pad8 uc16 addr32 */ \ +V(CHECK_NOT_BACK_REF, 34, 8) /* bc8 reg_idx24 addr32 */ \ +V(CHECK_NOT_BACK_REF_NO_CASE, 35, 8) /* bc8 reg_idx24 addr32 */ \ +V(CHECK_NOT_REGS_EQUAL, 36, 12) /* bc8 regidx24 reg_idx32 addr32 */ \ +V(LOOKUP_MAP1, 37, 12) /* bc8 pad8 start16 bit_map_addr32 addr32 */ \ +V(LOOKUP_MAP2, 38, 96) /* bc8 pad8 start16 half_nibble_map_addr32* */ \ +V(LOOKUP_MAP8, 39, 96) /* bc8 pad8 start16 byte_map addr32* */ \ +V(LOOKUP_HI_MAP8, 40, 96) /* bc8 start24 byte_map_addr32 addr32* */ \ +V(CHECK_REGISTER_LT, 41, 12) /* bc8 reg_idx24 value32 addr32 */ \ +V(CHECK_REGISTER_GE, 42, 12) /* bc8 reg_idx24 value32 addr32 */ \ +V(CHECK_REGISTER_EQ_POS, 43, 8) /* bc8 reg_idx24 addr32 */ \ +V(CHECK_AT_START, 44, 8) /* bc8 pad24 addr32 */ \ +V(CHECK_NOT_AT_START, 45, 8) /* bc8 pad24 addr32 */ \ +V(CHECK_GREEDY, 46, 8) /* bc8 pad24 addr32 */ \ +V(ADVANCE_CP_AND_GOTO, 47, 8) /* bc8 offset24 addr32 */ \ +V(SET_CURRENT_POSITION_FROM_END, 48, 4) /* bc8 idx24 */ #define DECLARE_BYTECODES(name, code, length) \ static const int BC_##name = code; diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc index 814e358721..11016c8238 100644 --- a/deps/v8/src/code-stubs.cc +++ b/deps/v8/src/code-stubs.cc @@ -73,12 +73,21 @@ SmartArrayPointer<const char> CodeStub::GetName() { void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) { + code->set_major_key(MajorKey()); + Isolate* isolate = masm->isolate(); SmartArrayPointer<const char> name = GetName(); PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name)); GDBJIT(AddCode(GDBJITInterface::STUB, *name, code)); Counters* counters = isolate->counters(); counters->total_stubs_code_size()->Increment(code->instruction_size()); + +#ifdef ENABLE_DISASSEMBLER + if (FLAG_print_code_stubs) { + code->Disassemble(*name); + PrintF("\n"); + } +#endif } @@ -116,16 +125,8 @@ Handle<Code> CodeStub::GetCode() { GetICState()); Handle<Code> new_object = factory->NewCode( desc, flags, masm.CodeObject(), NeedsImmovableCode()); - new_object->set_major_key(MajorKey()); - FinishCode(new_object); RecordCodeGeneration(*new_object, &masm); - -#ifdef ENABLE_DISASSEMBLER - if (FLAG_print_code_stubs) { - new_object->Disassemble(*GetName()); - PrintF("\n"); - } -#endif + FinishCode(new_object); if (UseSpecialCache()) { AddToSpecialCache(new_object); diff --git a/deps/v8/src/compiler-intrinsics.h b/deps/v8/src/compiler-intrinsics.h index b73e8ac750..3b9c59ea53 100644 --- a/deps/v8/src/compiler-intrinsics.h +++ b/deps/v8/src/compiler-intrinsics.h @@ -40,9 +40,6 @@ class CompilerIntrinsics { // Returns number of zero bits following most significant 1 bit. // Undefined for zero value. INLINE(static int CountLeadingZeros(uint32_t value)); - - // Returns the number of bits set. - INLINE(static int CountSetBits(uint32_t value)); }; #ifdef __GNUC__ @@ -54,10 +51,6 @@ int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { return __builtin_clz(value); } -int CompilerIntrinsics::CountSetBits(uint32_t value) { - return __builtin_popcount(value); -} - #elif defined(_MSC_VER) #pragma intrinsic(_BitScanForward) @@ -75,16 +68,6 @@ int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { return 31 - static_cast<int>(result); } -int CompilerIntrinsics::CountSetBits(uint32_t value) { - // Manually count set bits. - value = ((value >> 1) & 0x55555555) + (value & 0x55555555); - value = ((value >> 2) & 0x33333333) + (value & 0x33333333); - value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f); - value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff); - value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff); - return value; -} - #else #error Unsupported compiler #endif diff --git a/deps/v8/src/contexts.h b/deps/v8/src/contexts.h index 647c15c153..af5cb036c6 100644 --- a/deps/v8/src/contexts.h +++ b/deps/v8/src/contexts.h @@ -397,7 +397,7 @@ class Context: public FixedArray { GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSORS) #undef GLOBAL_CONTEXT_FIELD_ACCESSORS - // Lookup the slot called name, starting with the current context. + // Lookup the the slot called name, starting with the current context. // There are three possibilities: // // 1) result->IsContext(): diff --git a/deps/v8/src/conversions-inl.h b/deps/v8/src/conversions-inl.h index 77b260f036..b098a1c29c 100644 --- a/deps/v8/src/conversions-inl.h +++ b/deps/v8/src/conversions-inl.h @@ -228,7 +228,9 @@ double InternalStringToIntDouble(UnicodeCache* unicode_cache, } ASSERT(number != 0); - return ldexp(static_cast<double>(negative ? -number : number), exponent); + // The double could be constructed faster from number (mantissa), exponent + // and sign. Assuming it's a rare case more simple code is used. + return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); } diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc index 26d0bc10e1..45781cf0d4 100644 --- a/deps/v8/src/d8.cc +++ b/deps/v8/src/d8.cc @@ -318,7 +318,6 @@ static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) { const char kArrayBufferReferencePropName[] = "_is_array_buffer_"; const char kArrayBufferMarkerPropName[] = "_array_buffer_ref_"; -static const int kExternalArrayAllocationHeaderSize = 2; Handle<Value> Shell::CreateExternalArray(const Arguments& args, ExternalArrayType type, @@ -427,26 +426,14 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, } Persistent<Object> persistent_array = Persistent<Object>::New(array); + persistent_array.MakeWeak(data, ExternalArrayWeakCallback); + persistent_array.MarkIndependent(); if (data == NULL && length != 0) { - // Make sure the total size fits into a (signed) int. - static const int kMaxSize = 0x7fffffff; - if (length > (kMaxSize - sizeof(size_t)) / element_size) { - return ThrowException(String::New("Array exceeds maximum size (2G)")); - } - // Prepend the size of the allocated chunk to the data itself. - int total_size = length * element_size + - kExternalArrayAllocationHeaderSize * sizeof(size_t); - data = malloc(total_size); + data = calloc(length, element_size); if (data == NULL) { return ThrowException(String::New("Memory allocation failed.")); } - *reinterpret_cast<size_t*>(data) = total_size; - data = reinterpret_cast<size_t*>(data) + kExternalArrayAllocationHeaderSize; - memset(data, 0, length * element_size); - V8::AdjustAmountOfExternalAllocatedMemory(total_size); } - persistent_array.MakeWeak(data, ExternalArrayWeakCallback); - persistent_array.MarkIndependent(); array->SetIndexedPropertiesToExternalArrayData( reinterpret_cast<uint8_t*>(data) + offset, type, @@ -465,9 +452,6 @@ void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) { Handle<Object> converted_object = object->ToObject(); Local<Value> prop_value = converted_object->Get(prop_name); if (data != NULL && !prop_value->IsObject()) { - data = reinterpret_cast<size_t*>(data) - kExternalArrayAllocationHeaderSize; - V8::AdjustAmountOfExternalAllocatedMemory( - -static_cast<int>(*reinterpret_cast<size_t*>(data))); free(data); } object.Dispose(); @@ -993,8 +977,8 @@ void Shell::OnExit() { printf("+--------------------------------------------+-------------+\n"); delete [] counters; } - delete counters_file_; - delete counter_map_; + if (counters_file_ != NULL) + delete counters_file_; } #endif // V8_SHARED diff --git a/deps/v8/src/d8.js b/deps/v8/src/d8.js index 819135add4..bf269230b8 100644 --- a/deps/v8/src/d8.js +++ b/deps/v8/src/d8.js @@ -2174,7 +2174,7 @@ function DebugResponseDetails(response) { } var current_line = from_line + num; - var spacer = maxdigits - (1 + Math.floor(log10(current_line))); + spacer = maxdigits - (1 + Math.floor(log10(current_line))); if (current_line == Debug.State.currentSourceLine + 1) { for (var i = 0; i < maxdigits; i++) { result += '>'; diff --git a/deps/v8/src/debug-agent.cc b/deps/v8/src/debug-agent.cc index bdc7a578ac..511663d8ee 100644 --- a/deps/v8/src/debug-agent.cc +++ b/deps/v8/src/debug-agent.cc @@ -323,41 +323,41 @@ bool DebuggerAgentUtil::SendConnectMessage(const Socket* conn, const char* embedding_host) { static const int kBufferSize = 80; char buffer[kBufferSize]; // Sending buffer. + bool ok; int len; - int r; // Send the header. len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "Type: connect\r\n"); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "V8-Version: %s\r\n", v8::V8::GetVersion()); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "Protocol-Version: 1\r\n"); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; if (embedding_host != NULL) { len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "Embedding-Host: %s\r\n", embedding_host); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; } len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "%s: 0\r\n", kContentLength); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; // Terminate header with empty line. len = OS::SNPrintF(Vector<char>(buffer, kBufferSize), "\r\n"); - r = conn->Send(buffer, len); - if (r != len) return false; + ok = conn->Send(buffer, len); + if (!ok) return false; // No body for connect message. diff --git a/deps/v8/src/debug-debugger.js b/deps/v8/src/debug-debugger.js index 91838e8ad0..802f6224c4 100644 --- a/deps/v8/src/debug-debugger.js +++ b/deps/v8/src/debug-debugger.js @@ -1957,7 +1957,7 @@ DebugCommandProcessor.prototype.frameForScopeRequest_ = function(request) { if (request.arguments && !IS_UNDEFINED(request.arguments.frameNumber)) { frame_index = request.arguments.frameNumber; if (frame_index < 0 || this.exec_state_.frameCount() <= frame_index) { - throw new Error('Invalid frame number'); + return response.failed('Invalid frame number'); } return this.exec_state_.frame(frame_index); } else { @@ -1966,44 +1966,20 @@ DebugCommandProcessor.prototype.frameForScopeRequest_ = function(request) { }; -// Gets scope host object from request. It is either a function -// ('functionHandle' argument must be specified) or a stack frame -// ('frameNumber' may be specified and the current frame is taken by default). -DebugCommandProcessor.prototype.scopeHolderForScopeRequest_ = - function(request) { - if (request.arguments && "functionHandle" in request.arguments) { - if (!IS_NUMBER(request.arguments.functionHandle)) { - throw new Error('Function handle must be a number'); - } - var function_mirror = LookupMirror(request.arguments.functionHandle); - if (!function_mirror) { - throw new Error('Failed to find function object by handle'); - } - if (!function_mirror.isFunction()) { - throw new Error('Value of non-function type is found by handle'); - } - return function_mirror; - } else { - // No frames no scopes. - if (this.exec_state_.frameCount() == 0) { - throw new Error('No scopes'); - } - - // Get the frame for which the scopes are requested. - var frame = this.frameForScopeRequest_(request); - return frame; +DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) { + // No frames no scopes. + if (this.exec_state_.frameCount() == 0) { + return response.failed('No scopes'); } -} + // Get the frame for which the scopes are requested. + var frame = this.frameForScopeRequest_(request); -DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) { - var scope_holder = this.scopeHolderForScopeRequest_(request); - - // Fill all scopes for this frame or function. - var total_scopes = scope_holder.scopeCount(); + // Fill all scopes for this frame. + var total_scopes = frame.scopeCount(); var scopes = []; for (var i = 0; i < total_scopes; i++) { - scopes.push(scope_holder.scope(i)); + scopes.push(frame.scope(i)); } response.body = { fromScope: 0, @@ -2015,19 +1991,24 @@ DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) { DebugCommandProcessor.prototype.scopeRequest_ = function(request, response) { - // Get the frame or function for which the scope is requested. - var scope_holder = this.scopeHolderForScopeRequest_(request); + // No frames no scopes. + if (this.exec_state_.frameCount() == 0) { + return response.failed('No scopes'); + } + + // Get the frame for which the scope is requested. + var frame = this.frameForScopeRequest_(request); // With no scope argument just return top scope. var scope_index = 0; if (request.arguments && !IS_UNDEFINED(request.arguments.number)) { scope_index = %ToNumber(request.arguments.number); - if (scope_index < 0 || scope_holder.scopeCount() <= scope_index) { + if (scope_index < 0 || frame.scopeCount() <= scope_index) { return response.failed('Invalid scope number'); } } - response.body = scope_holder.scope(scope_index); + response.body = frame.scope(scope_index); }; diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc index 99256ba21a..f8a1ecf4f9 100644 --- a/deps/v8/src/debug.cc +++ b/deps/v8/src/debug.cc @@ -1857,6 +1857,13 @@ static void RedirectActivationsToRecompiledCodeOnThread( // break slots. debug_break_slot_count++; } + if (frame_code->has_self_optimization_header() && + !new_code->has_self_optimization_header()) { + delta -= FullCodeGenerator::self_optimization_header_size(); + } else { + ASSERT(frame_code->has_self_optimization_header() == + new_code->has_self_optimization_header()); + } int debug_break_slot_bytes = debug_break_slot_count * Assembler::kDebugBreakSlotLength; if (FLAG_trace_deopt) { diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h index 7ec78015c6..474b90bd21 100644 --- a/deps/v8/src/debug.h +++ b/deps/v8/src/debug.h @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -245,8 +245,6 @@ class Debug { bool IsBreakOnException(ExceptionBreakType type); void PrepareStep(StepAction step_action, int step_count); void ClearStepping(); - void ClearStepOut(); - bool IsStepping() { return thread_local_.step_count_ > 0; } bool StepNextContinue(BreakLocationIterator* break_location_iterator, JavaScriptFrame* frame); static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); @@ -466,6 +464,7 @@ class Debug { void ActivateStepIn(StackFrame* frame); void ClearStepIn(); void ActivateStepOut(StackFrame* frame); + void ClearStepOut(); void ClearStepNext(); // Returns whether the compile succeeded. void RemoveDebugInfo(Handle<DebugInfo> debug_info); diff --git a/deps/v8/src/double.h b/deps/v8/src/double.h index fcf6906af7..16a3245e9a 100644 --- a/deps/v8/src/double.h +++ b/deps/v8/src/double.h @@ -130,6 +130,12 @@ class Double { return (d64 & kExponentMask) == kExponentMask; } + bool IsNan() const { + uint64_t d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) != 0); + } + bool IsInfinite() const { uint64_t d64 = AsUint64(); return ((d64 & kExponentMask) == kExponentMask) && diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc index 26d3dc135c..aa51ea9b78 100644 --- a/deps/v8/src/elements.cc +++ b/deps/v8/src/elements.cc @@ -1332,8 +1332,18 @@ ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { void ElementsAccessor::InitializeOncePerProcess() { + static struct ConcreteElementsAccessors { +#define ACCESSOR_STRUCT(Class, Kind, Store) Class* Kind##_handler; + ELEMENTS_LIST(ACCESSOR_STRUCT) +#undef ACCESSOR_STRUCT + } element_accessors = { +#define ACCESSOR_INIT(Class, Kind, Store) new Class(#Kind), + ELEMENTS_LIST(ACCESSOR_INIT) +#undef ACCESSOR_INIT + }; + static ElementsAccessor* accessor_array[] = { -#define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), +#define ACCESSOR_ARRAY(Class, Kind, Store) element_accessors.Kind##_handler, ELEMENTS_LIST(ACCESSOR_ARRAY) #undef ACCESSOR_ARRAY }; @@ -1345,14 +1355,6 @@ void ElementsAccessor::InitializeOncePerProcess() { } -void ElementsAccessor::TearDown() { -#define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; - ELEMENTS_LIST(ACCESSOR_DELETE) -#undef ACCESSOR_DELETE - elements_accessors_ = NULL; -} - - template <typename ElementsAccessorSubclass, typename ElementsKindTraits> MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>:: diff --git a/deps/v8/src/elements.h b/deps/v8/src/elements.h index 51d402d341..ff97c08324 100644 --- a/deps/v8/src/elements.h +++ b/deps/v8/src/elements.h @@ -131,7 +131,6 @@ class ElementsAccessor { static ElementsAccessor* ForArray(FixedArrayBase* array); static void InitializeOncePerProcess(); - static void TearDown(); protected: friend class NonStrictArgumentsElementsAccessor; diff --git a/deps/v8/src/extensions/externalize-string-extension.cc b/deps/v8/src/extensions/externalize-string-extension.cc index 50d876136f..9fbf329818 100644 --- a/deps/v8/src/extensions/externalize-string-extension.cc +++ b/deps/v8/src/extensions/externalize-string-extension.cc @@ -133,8 +133,11 @@ v8::Handle<v8::Value> ExternalizeStringExtension::IsAscii( void ExternalizeStringExtension::Register() { - static ExternalizeStringExtension externalize_extension; - static v8::DeclareExtension declaration(&externalize_extension); + static ExternalizeStringExtension* externalize_extension = NULL; + if (externalize_extension == NULL) + externalize_extension = new ExternalizeStringExtension; + static v8::DeclareExtension externalize_extension_declaration( + externalize_extension); } } } // namespace v8::internal diff --git a/deps/v8/src/extensions/gc-extension.cc b/deps/v8/src/extensions/gc-extension.cc index f921552aaa..573797e174 100644 --- a/deps/v8/src/extensions/gc-extension.cc +++ b/deps/v8/src/extensions/gc-extension.cc @@ -46,8 +46,9 @@ v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { void GCExtension::Register() { - static GCExtension gc_extension; - static v8::DeclareExtension declaration(&gc_extension); + static GCExtension* gc_extension = NULL; + if (gc_extension == NULL) gc_extension = new GCExtension(); + static v8::DeclareExtension gc_extension_declaration(gc_extension); } } } // namespace v8::internal diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc index 6bb7893746..e8a9f26a5c 100644 --- a/deps/v8/src/factory.cc +++ b/deps/v8/src/factory.cc @@ -291,15 +291,6 @@ Handle<Context> Factory::NewGlobalContext() { } -Handle<Context> Factory::NewModuleContext(Handle<Context> previous, - Handle<ScopeInfo> scope_info) { - CALL_HEAP_FUNCTION( - isolate(), - isolate()->heap()->AllocateModuleContext(*previous, *scope_info), - Context); -} - - Handle<Context> Factory::NewFunctionContext(int length, Handle<JSFunction> function) { CALL_HEAP_FUNCTION( @@ -333,9 +324,10 @@ Handle<Context> Factory::NewWithContext(Handle<JSFunction> function, } -Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function, - Handle<Context> previous, - Handle<ScopeInfo> scope_info) { +Handle<Context> Factory::NewBlockContext( + Handle<JSFunction> function, + Handle<Context> previous, + Handle<ScopeInfo> scope_info) { CALL_HEAP_FUNCTION( isolate(), isolate()->heap()->AllocateBlockContext(*function, @@ -936,13 +928,6 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, } -Handle<JSModule> Factory::NewJSModule() { - CALL_HEAP_FUNCTION( - isolate(), - isolate()->heap()->AllocateJSModule(), JSModule); -} - - Handle<GlobalObject> Factory::NewGlobalObject( Handle<JSFunction> constructor) { CALL_HEAP_FUNCTION(isolate(), diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h index 06aad1bef6..786d4a983a 100644 --- a/deps/v8/src/factory.h +++ b/deps/v8/src/factory.h @@ -162,12 +162,9 @@ class Factory { // Create a global (but otherwise uninitialized) context. Handle<Context> NewGlobalContext(); - // Create a module context. - Handle<Context> NewModuleContext(Handle<Context> previous, - Handle<ScopeInfo> scope_info); - // Create a function context. - Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function); + Handle<Context> NewFunctionContext(int length, + Handle<JSFunction> function); // Create a catch context. Handle<Context> NewCatchContext(Handle<JSFunction> function, @@ -180,7 +177,7 @@ class Factory { Handle<Context> previous, Handle<JSObject> extension); - // Create a block context. + // Create a 'block' context. Handle<Context> NewBlockContext(Handle<JSFunction> function, Handle<Context> previous, Handle<ScopeInfo> scope_info); @@ -265,9 +262,6 @@ class Factory { // runtime. Handle<JSObject> NewJSObjectFromMap(Handle<Map> map); - // JS modules are pretenured. - Handle<JSModule> NewJSModule(); - // JS arrays are pretenured when allocated by the parser. Handle<JSArray> NewJSArray(int capacity, ElementsKind elements_kind = FAST_ELEMENTS, diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index 62a9782859..75697a8906 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -132,8 +132,6 @@ public: // Flags for language modes and experimental language features. DEFINE_bool(use_strict, false, "enforce strict mode") -DEFINE_bool(es52_globals, false, - "activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false, "enable harmony block scoping") @@ -167,12 +165,7 @@ DEFINE_bool(eliminate_dead_phis, true, "eliminate dead phis") DEFINE_bool(use_gvn, true, "use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true, "use function inlining") -DEFINE_int(max_inlined_source_size, 600, - "maximum source size in bytes considered for a single inlining") -DEFINE_int(max_inlined_nodes, 196, - "maximum number of AST nodes considered for a single inlining") -DEFINE_int(max_inlined_nodes_cumulative, 196, - "maximum cumulative number of AST nodes considered for inlining") +DEFINE_bool(limit_inlining, true, "limit code size growth from inlining") DEFINE_bool(loop_invariant_code_motion, true, "loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true, @@ -195,8 +188,6 @@ DEFINE_bool(trap_on_deopt, false, "put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining") DEFINE_bool(use_osr, true, "use on-stack replacement") -DEFINE_bool(array_bounds_checks_elimination, true, - "perform array bounds checks elimination") DEFINE_bool(trace_osr, false, "trace on-stack replacement") DEFINE_int(stress_runs, 0, "number of stress runs") diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc index e265341b1a..0571a813f5 100644 --- a/deps/v8/src/frames.cc +++ b/deps/v8/src/frames.cc @@ -1359,28 +1359,34 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* // ------------------------------------------------------------------------- int NumRegs(RegList reglist) { - return CompilerIntrinsics::CountSetBits(reglist); + int n = 0; + while (reglist != 0) { + n++; + reglist &= reglist - 1; // clear one bit + } + return n; } struct JSCallerSavedCodeData { + JSCallerSavedCodeData() { + int i = 0; + for (int r = 0; r < kNumRegs; r++) + if ((kJSCallerSaved & (1 << r)) != 0) + reg_code[i++] = r; + + ASSERT(i == kNumJSCallerSaved); + } int reg_code[kNumJSCallerSaved]; }; -JSCallerSavedCodeData caller_saved_code_data; -void SetUpJSCallerSavedCodeData() { - int i = 0; - for (int r = 0; r < kNumRegs; r++) - if ((kJSCallerSaved & (1 << r)) != 0) - caller_saved_code_data.reg_code[i++] = r; - - ASSERT(i == kNumJSCallerSaved); -} +static LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data = + LAZY_INSTANCE_INITIALIZER; int JSCallerSavedCode(int n) { ASSERT(0 <= n && n < kNumJSCallerSaved); - return caller_saved_code_data.reg_code[n]; + return caller_saved_code_data.Get().reg_code[n]; } diff --git a/deps/v8/src/frames.h b/deps/v8/src/frames.h index 7178bd413a..9071555197 100644 --- a/deps/v8/src/frames.h +++ b/deps/v8/src/frames.h @@ -40,8 +40,6 @@ typedef uint32_t RegList; // Get the number of registers in a given register list. int NumRegs(RegList list); -void SetUpJSCallerSavedCodeData(); - // Return the code of the n-th saved register available to JavaScript. int JSCallerSavedCode(int n); diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc index 9b1df4ee73..44fe011a4e 100644 --- a/deps/v8/src/full-codegen.cc +++ b/deps/v8/src/full-codegen.cc @@ -316,6 +316,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { code->set_optimizable(info->IsOptimizable() && !info->function()->flags()->Contains(kDontOptimize) && info->function()->scope()->AllowsLazyRecompilation()); + code->set_self_optimization_header(cgen.has_self_optimization_header_); cgen.PopulateDeoptimizationData(code); cgen.PopulateTypeFeedbackInfo(code); cgen.PopulateTypeFeedbackCells(code); @@ -331,6 +332,9 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { code->set_stack_check_table_offset(table_offset); CodeGenerator::PrintCode(code, info); info->SetCode(code); // May be an empty handle. + if (!code.is_null()) { + isolate->runtime_profiler()->NotifyCodeGenerated(code->instruction_size()); + } #ifdef ENABLE_GDB_JIT_INTERFACE if (FLAG_gdbjit && !code.is_null()) { GDBJITLineInfo* lineinfo = @@ -569,91 +573,88 @@ void FullCodeGenerator::DoTest(const TestContext* context) { void FullCodeGenerator::VisitDeclarations( ZoneList<Declaration*>* declarations) { - ZoneList<Handle<Object> >* saved_globals = globals_; - ZoneList<Handle<Object> > inner_globals(10); - globals_ = &inner_globals; + int save_global_count = global_count_; + global_count_ = 0; AstVisitor::VisitDeclarations(declarations); - if (!globals_->is_empty()) { + + // Batch declare global functions and variables. + if (global_count_ > 0) { + Handle<FixedArray> array = + isolate()->factory()->NewFixedArray(2 * global_count_, TENURED); + int length = declarations->length(); + for (int j = 0, i = 0; i < length; i++) { + Declaration* decl = declarations->at(i); + Variable* var = decl->proxy()->var(); + + if (var->IsUnallocated()) { + array->set(j++, *(var->name())); + FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration(); + if (fun_decl == NULL) { + if (var->binding_needs_init()) { + // In case this binding needs initialization use the hole. + array->set_the_hole(j++); + } else { + array->set_undefined(j++); + } + } else { + Handle<SharedFunctionInfo> function = + Compiler::BuildFunctionInfo(fun_decl->fun(), script()); + // Check for stack-overflow exception. + if (function.is_null()) { + SetStackOverflow(); + return; + } + array->set(j++, *function); + } + } + } // Invoke the platform-dependent code generator to do the actual // declaration the global functions and variables. - Handle<FixedArray> array = - isolate()->factory()->NewFixedArray(globals_->length(), TENURED); - for (int i = 0; i < globals_->length(); ++i) - array->set(i, *globals_->at(i)); DeclareGlobals(array); } - globals_ = saved_globals; + global_count_ = save_global_count; } -void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { - Handle<JSModule> instance = module->interface()->Instance(); - ASSERT(!instance.is_null()); +void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { + EmitDeclaration(decl->proxy(), decl->mode(), NULL); +} - // Allocate a module context statically. - Block* block = module->body(); - Scope* saved_scope = scope(); - scope_ = block->scope(); - Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); - - // Generate code for module creation and linking. - Comment cmnt(masm_, "[ ModuleLiteral"); - SetStatementPosition(block); - - if (scope_info->HasContext()) { - // Set up module context. - __ Push(scope_info); - __ Push(instance); - __ CallRuntime(Runtime::kPushModuleContext, 2); - StoreToFrameField( - StandardFrameConstants::kContextOffset, context_register()); - } - { - Comment cmnt(masm_, "[ Declarations"); - VisitDeclarations(scope_->declarations()); - } +void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { + EmitDeclaration(decl->proxy(), decl->mode(), decl->fun()); +} - scope_ = saved_scope; - if (scope_info->HasContext()) { - // Pop module context. - LoadContextField(context_register(), Context::PREVIOUS_INDEX); - // Update local stack frame context field. - StoreToFrameField( - StandardFrameConstants::kContextOffset, context_register()); - } - // Populate module instance object. - const PropertyAttributes attr = - static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); - for (Interface::Iterator it = module->interface()->iterator(); - !it.done(); it.Advance()) { - if (it.interface()->IsModule()) { - Handle<Object> value = it.interface()->Instance(); - ASSERT(!value.is_null()); - JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode); - } else { - // TODO(rossberg): set proper getters instead of undefined... - // instance->DefineAccessor(*it.name(), ACCESSOR_GETTER, *getter, attr); - Handle<Object> value(isolate()->heap()->undefined_value()); - JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode); - } - } - USE(instance->PreventExtensions()); +void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) { + EmitDeclaration(decl->proxy(), decl->mode(), NULL); +} + + +void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { + EmitDeclaration(decl->proxy(), decl->mode(), NULL); +} + + +void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { + // TODO(rossberg) +} + + +void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { + // TODO(rossberg) } void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { - // Noting to do. - // The instance object is resolved statically through the module's interface. + // TODO(rossberg) } void FullCodeGenerator::VisitModulePath(ModulePath* module) { - // Noting to do. - // The instance object is resolved statically through the module's interface. + // TODO(rossberg) } @@ -915,9 +916,9 @@ void FullCodeGenerator::VisitBlock(Block* stmt) { Scope* saved_scope = scope(); // Push a block context when entering a block with block scoped variables. - if (stmt->scope() != NULL) { + if (stmt->block_scope() != NULL) { { Comment cmnt(masm_, "[ Extend block context"); - scope_ = stmt->scope(); + scope_ = stmt->block_scope(); Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; __ Push(scope_info); @@ -944,7 +945,7 @@ void FullCodeGenerator::VisitBlock(Block* stmt) { PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); // Pop block context if necessary. - if (stmt->scope() != NULL) { + if (stmt->block_scope() != NULL) { LoadContextField(context_register(), Context::PREVIOUS_INDEX); // Update local stack frame context field. StoreToFrameField(StandardFrameConstants::kContextOffset, diff --git a/deps/v8/src/full-codegen.h b/deps/v8/src/full-codegen.h index 0e0ffe924b..58d59862a5 100644 --- a/deps/v8/src/full-codegen.h +++ b/deps/v8/src/full-codegen.h @@ -83,17 +83,22 @@ class FullCodeGenerator: public AstVisitor { scope_(info->scope()), nesting_stack_(NULL), loop_depth_(0), - globals_(NULL), + global_count_(0), context_(NULL), bailout_entries_(info->HasDeoptimizationSupport() ? info->function()->ast_node_count() : 0), stack_checks_(2), // There's always at least one. type_feedback_cells_(info->HasDeoptimizationSupport() ? info->function()->ast_node_count() : 0), - ic_total_count_(0) { } + ic_total_count_(0), + has_self_optimization_header_(false) { } static bool MakeCode(CompilationInfo* info); + // Returns the platform-specific size in bytes of the self-optimization + // header. + static int self_optimization_header_size(); + // Encode state and pc-offset as a BitField<type, start, size>. // Only use 30 bits because we encode the result as a smi. class StateField : public BitField<State, 0, 1> { }; @@ -202,7 +207,7 @@ class FullCodeGenerator: public AstVisitor { virtual ~NestedBlock() {} virtual NestedStatement* Exit(int* stack_depth, int* context_length) { - if (statement()->AsBlock()->scope() != NULL) { + if (statement()->AsBlock()->block_scope() != NULL) { ++(*context_length); } return previous_; @@ -413,9 +418,12 @@ class FullCodeGenerator: public AstVisitor { Label* if_true, Label* if_false); - // If enabled, emit debug code for checking that the current context is - // neither a with nor a catch context. - void EmitDebugCheckDeclarationContext(Variable* variable); + // Platform-specific code for a variable, constant, or function + // declaration. Functions have an initial value. + // Increments global_count_ for unallocated variables. + void EmitDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function); // Platform-specific code for checking the stack limit at the back edge of // a loop. @@ -545,8 +553,12 @@ class FullCodeGenerator: public AstVisitor { Handle<Script> script() { return info_->script(); } bool is_eval() { return info_->is_eval(); } bool is_native() { return info_->is_native(); } - bool is_classic_mode() { return language_mode() == CLASSIC_MODE; } - LanguageMode language_mode() { return function()->language_mode(); } + bool is_classic_mode() { + return language_mode() == CLASSIC_MODE; + } + LanguageMode language_mode() { + return function()->language_mode(); + } FunctionLiteral* function() { return info_->function(); } Scope* scope() { return scope_; } @@ -778,12 +790,13 @@ class FullCodeGenerator: public AstVisitor { Label return_label_; NestedStatement* nesting_stack_; int loop_depth_; - ZoneList<Handle<Object> >* globals_; + int global_count_; const ExpressionContext* context_; ZoneList<BailoutEntry> bailout_entries_; ZoneList<BailoutEntry> stack_checks_; ZoneList<TypeFeedbackCellEntry> type_feedback_cells_; int ic_total_count_; + bool has_self_optimization_header_; Handle<FixedArray> handler_table_; Handle<JSGlobalPropertyCell> profiling_counter_; diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc index def1604ac7..416ecbd211 100644 --- a/deps/v8/src/handles.cc +++ b/deps/v8/src/handles.cc @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -729,9 +729,9 @@ Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate); for (int i = 0; i < descs->number_of_descriptors(); i++) { - if (descs->IsProperty(i) && !descs->GetDetails(i).IsDontEnum()) { + if (descs->IsProperty(i) && !descs->IsDontEnum(i)) { storage->set(index, descs->GetKey(i)); - PropertyDetails details = descs->GetDetails(i); + PropertyDetails details(descs->GetDetails(i)); sort_array->set(index, Smi::FromInt(details.index())); if (!indices.is_null()) { if (details.type() != FIELD) { diff --git a/deps/v8/src/hashmap.h b/deps/v8/src/hashmap.h index 91843b81b8..5aeb8951ed 100644 --- a/deps/v8/src/hashmap.h +++ b/deps/v8/src/hashmap.h @@ -63,9 +63,7 @@ class TemplateHashMapImpl { Entry* Lookup(void* key, uint32_t hash, bool insert); // Removes the entry with matching key. - // It returns the value of the deleted entry - // or null if there is no value for such key. - void* Remove(void* key, uint32_t hash); + void Remove(void* key, uint32_t hash); // Empties the hash map (occupancy() == 0). void Clear(); @@ -148,15 +146,14 @@ typename TemplateHashMapImpl<P>::Entry* TemplateHashMapImpl<P>::Lookup( template<class P> -void* TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) { +void TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) { // Lookup the entry for the key to remove. Entry* p = Probe(key, hash); if (p->key == NULL) { // Key not found nothing to remove. - return NULL; + return; } - void* value = p->value; // To remove an entry we need to ensure that it does not create an empty // entry that will cause the search for another entry to stop too soon. If all // the entries between the entry to remove and the next empty slot have their @@ -205,7 +202,6 @@ void* TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) { // Clear the entry which is allowed to en emptied. p->key = NULL; occupancy_--; - return value; } diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h index e12895a283..706d2886b9 100644 --- a/deps/v8/src/heap-inl.h +++ b/deps/v8/src/heap-inl.h @@ -460,16 +460,15 @@ MaybeObject* Heap::PrepareForCompare(String* str) { } -intptr_t Heap::AdjustAmountOfExternalAllocatedMemory( - intptr_t change_in_bytes) { +int Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) { ASSERT(HasBeenSetUp()); - intptr_t amount = amount_of_external_allocated_memory_ + change_in_bytes; + int 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 = + int 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_) { diff --git a/deps/v8/src/heap-profiler.cc b/deps/v8/src/heap-profiler.cc index 2e971a51b4..8be6f27685 100644 --- a/deps/v8/src/heap-profiler.cc +++ b/deps/v8/src/heap-profiler.cc @@ -33,6 +33,7 @@ namespace v8 { namespace internal { + HeapProfiler::HeapProfiler() : snapshots_(new HeapSnapshotsCollection()), next_snapshot_uid_(1) { @@ -85,24 +86,6 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(String* name, } -void HeapProfiler::StartHeapObjectsTracking() { - ASSERT(Isolate::Current()->heap_profiler() != NULL); - Isolate::Current()->heap_profiler()->StartHeapObjectsTrackingImpl(); -} - - -void HeapProfiler::StopHeapObjectsTracking() { - ASSERT(Isolate::Current()->heap_profiler() != NULL); - Isolate::Current()->heap_profiler()->StopHeapObjectsTrackingImpl(); -} - - -void HeapProfiler::PushHeapObjectsStats(v8::OutputStream* stream) { - ASSERT(Isolate::Current()->heap_profiler() != NULL); - return Isolate::Current()->heap_profiler()->PushHeapObjectsStatsImpl(stream); -} - - void HeapProfiler::DefineWrapperClass( uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback) { ASSERT(class_id != v8::HeapProfiler::kPersistentHandleNoClassId); @@ -153,20 +136,6 @@ HeapSnapshot* HeapProfiler::TakeSnapshotImpl(String* name, return TakeSnapshotImpl(snapshots_->names()->GetName(name), type, control); } -void HeapProfiler::StartHeapObjectsTrackingImpl() { - snapshots_->StartHeapObjectsTracking(); -} - - -void HeapProfiler::PushHeapObjectsStatsImpl(OutputStream* stream) { - snapshots_->PushHeapObjectsStats(stream); -} - - -void HeapProfiler::StopHeapObjectsTrackingImpl() { - snapshots_->StopHeapObjectsTracking(); -} - int HeapProfiler::GetSnapshotsCount() { HeapProfiler* profiler = Isolate::Current()->heap_profiler(); @@ -189,15 +158,6 @@ HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) { } -SnapshotObjectId HeapProfiler::GetSnapshotObjectId(Handle<Object> obj) { - if (!obj->IsHeapObject()) - return v8::HeapProfiler::kUnknownObjectId; - HeapProfiler* profiler = Isolate::Current()->heap_profiler(); - ASSERT(profiler != NULL); - return profiler->snapshots_->FindObjectId(HeapObject::cast(*obj)->address()); -} - - void HeapProfiler::DeleteAllSnapshots() { HeapProfiler* profiler = Isolate::Current()->heap_profiler(); ASSERT(profiler != NULL); diff --git a/deps/v8/src/heap-profiler.h b/deps/v8/src/heap-profiler.h index 96b042d3cb..ef5c4f4b4a 100644 --- a/deps/v8/src/heap-profiler.h +++ b/deps/v8/src/heap-profiler.h @@ -44,6 +44,8 @@ class HeapSnapshotsCollection; } \ } while (false) +// The HeapProfiler writes data to the log files, which can be postprocessed +// to generate .hp files for use by the GHC/Valgrind tool hp2ps. class HeapProfiler { public: static void SetUp(); @@ -55,14 +57,9 @@ class HeapProfiler { static HeapSnapshot* TakeSnapshot(String* name, int type, v8::ActivityControl* control); - - static void StartHeapObjectsTracking(); - static void StopHeapObjectsTracking(); - static void PushHeapObjectsStats(OutputStream* stream); static int GetSnapshotsCount(); static HeapSnapshot* GetSnapshot(int index); static HeapSnapshot* FindSnapshot(unsigned uid); - static SnapshotObjectId GetSnapshotObjectId(Handle<Object> obj); static void DeleteAllSnapshots(); void ObjectMoveEvent(Address from, Address to); @@ -87,10 +84,6 @@ class HeapProfiler { v8::ActivityControl* control); void ResetSnapshots(); - void StartHeapObjectsTrackingImpl(); - void StopHeapObjectsTrackingImpl(); - void PushHeapObjectsStatsImpl(OutputStream* stream); - HeapSnapshotsCollection* snapshots_; unsigned next_snapshot_uid_; List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc index e2e0e9eff3..e0116192ce 100644 --- a/deps/v8/src/heap.cc +++ b/deps/v8/src/heap.cc @@ -42,7 +42,6 @@ #include "natives.h" #include "objects-visiting.h" #include "objects-visiting-inl.h" -#include "once.h" #include "runtime-profiler.h" #include "scopeinfo.h" #include "snapshot.h" @@ -61,26 +60,33 @@ namespace v8 { namespace internal { +static LazyMutex gc_initializer_mutex = LAZY_MUTEX_INITIALIZER; + Heap::Heap() : isolate_(NULL), // semispace_size_ should be a power of 2 and old_generation_size_ should be // a multiple of Page::kPageSize. -#if defined(ANDROID) -#define LUMP_OF_MEMORY (128 * KB) - code_range_size_(0), -#elif defined(V8_TARGET_ARCH_X64) +#if defined(V8_TARGET_ARCH_X64) #define LUMP_OF_MEMORY (2 * MB) code_range_size_(512*MB), #else #define LUMP_OF_MEMORY MB code_range_size_(0), #endif +#if defined(ANDROID) + reserved_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)), + max_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)), + initial_semispace_size_(Page::kPageSize), + max_old_generation_size_(192*MB), + max_executable_size_(max_old_generation_size_), +#else reserved_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), initial_semispace_size_(Page::kPageSize), max_old_generation_size_(700ul * LUMP_OF_MEMORY), max_executable_size_(256l * LUMP_OF_MEMORY), +#endif // Variables set based on semispace_size_ and old_generation_size_ in // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) @@ -238,17 +244,12 @@ int Heap::GcSafeSizeOfOldObject(HeapObject* object) { GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space, const char** reason) { // Is global GC requested? - if (space != NEW_SPACE) { + if (space != NEW_SPACE || FLAG_gc_global) { isolate_->counters()->gc_compactor_caused_by_request()->Increment(); *reason = "GC in old space requested"; return MARK_COMPACTOR; } - if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) { - *reason = "GC in old space forced by flags"; - return MARK_COMPACTOR; - } - // Is enough data promoted to justify a global GC? if (OldGenerationPromotionLimitReached()) { isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment(); @@ -1129,27 +1130,6 @@ void PromotionQueue::RelocateQueueHead() { } -class ScavengeWeakObjectRetainer : public WeakObjectRetainer { - public: - explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) { } - - virtual Object* RetainAs(Object* object) { - if (!heap_->InFromSpace(object)) { - return object; - } - - MapWord map_word = HeapObject::cast(object)->map_word(); - if (map_word.IsForwardingAddress()) { - return map_word.ToForwardingAddress(); - } - return NULL; - } - - private: - Heap* heap_; -}; - - void Heap::Scavenge() { #ifdef DEBUG if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); @@ -1248,9 +1228,6 @@ void Heap::Scavenge() { } incremental_marking()->UpdateMarkingDequeAfterScavenge(); - ScavengeWeakObjectRetainer weak_object_retainer(this); - ProcessWeakReferences(&weak_object_retainer); - ASSERT(new_space_front == new_space_.top()); // Set age mark. @@ -1337,8 +1314,7 @@ void Heap::UpdateReferencesInExternalStringTable( static Object* ProcessFunctionWeakReferences(Heap* heap, Object* function, - WeakObjectRetainer* retainer, - bool record_slots) { + WeakObjectRetainer* retainer) { Object* undefined = heap->undefined_value(); Object* head = undefined; JSFunction* tail = NULL; @@ -1355,12 +1331,6 @@ static Object* ProcessFunctionWeakReferences(Heap* heap, // Subsequent elements in the list. ASSERT(tail != NULL); tail->set_next_function_link(retain); - if (record_slots) { - Object** next_function = - HeapObject::RawField(tail, JSFunction::kNextFunctionLinkOffset); - heap->mark_compact_collector()->RecordSlot( - next_function, next_function, retain); - } } // Retained function is new tail. candidate_function = reinterpret_cast<JSFunction*>(retain); @@ -1389,15 +1359,6 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { Object* head = undefined; Context* tail = NULL; Object* candidate = global_contexts_list_; - - // We don't record weak slots during marking or scavenges. - // Instead we do it once when we complete mark-compact cycle. - // Note that write barrier has no effect if we are already in the middle of - // compacting mark-sweep cycle and we have to record slots manually. - bool record_slots = - gc_state() == MARK_COMPACT && - mark_compact_collector()->is_compacting(); - while (candidate != undefined) { // Check whether to keep the candidate in the list. Context* candidate_context = reinterpret_cast<Context*>(candidate); @@ -1413,14 +1374,6 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { Context::NEXT_CONTEXT_LINK, retain, UPDATE_WRITE_BARRIER); - - if (record_slots) { - Object** next_context = - HeapObject::RawField( - tail, FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK)); - mark_compact_collector()->RecordSlot( - next_context, next_context, retain); - } } // Retained context is new tail. candidate_context = reinterpret_cast<Context*>(retain); @@ -1433,19 +1386,11 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { ProcessFunctionWeakReferences( this, candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST), - retainer, - record_slots); + retainer); candidate_context->set_unchecked(this, Context::OPTIMIZED_FUNCTIONS_LIST, function_list_head, UPDATE_WRITE_BARRIER); - if (record_slots) { - Object** optimized_functions = - HeapObject::RawField( - tail, FixedArray::SizeFor(Context::OPTIMIZED_FUNCTIONS_LIST)); - mark_compact_collector()->RecordSlot( - optimized_functions, optimized_functions, function_list_head); - } } // Move to next element in the list. @@ -1545,27 +1490,6 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor, } -STATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) == 0); - - -INLINE(static HeapObject* EnsureDoubleAligned(Heap* heap, - HeapObject* object, - int size)); - -static HeapObject* EnsureDoubleAligned(Heap* heap, - HeapObject* object, - int size) { - if ((OffsetFrom(object->address()) & kDoubleAlignmentMask) != 0) { - heap->CreateFillerObjectAt(object->address(), kPointerSize); - return HeapObject::FromAddress(object->address() + kPointerSize); - } else { - heap->CreateFillerObjectAt(object->address() + size - kPointerSize, - kPointerSize); - return object; - } -} - - enum LoggingAndProfiling { LOGGING_AND_PROFILING_ENABLED, LOGGING_AND_PROFILING_DISABLED @@ -1689,10 +1613,7 @@ class ScavengingVisitor : public StaticVisitorBase { } } - - template<ObjectContents object_contents, - SizeRestriction size_restriction, - int alignment> + template<ObjectContents object_contents, SizeRestriction size_restriction> static inline void EvacuateObject(Map* map, HeapObject** slot, HeapObject* object, @@ -1701,26 +1622,19 @@ class ScavengingVisitor : public StaticVisitorBase { (object_size <= Page::kMaxNonCodeHeapObjectSize)); SLOW_ASSERT(object->Size() == object_size); - int allocation_size = object_size; - if (alignment != kObjectAlignment) { - ASSERT(alignment == kDoubleAlignment); - allocation_size += kPointerSize; - } - Heap* heap = map->GetHeap(); if (heap->ShouldBePromoted(object->address(), object_size)) { MaybeObject* maybe_result; if ((size_restriction != SMALL) && - (allocation_size > Page::kMaxNonCodeHeapObjectSize)) { - maybe_result = heap->lo_space()->AllocateRaw(allocation_size, + (object_size > Page::kMaxNonCodeHeapObjectSize)) { + maybe_result = heap->lo_space()->AllocateRaw(object_size, NOT_EXECUTABLE); } else { if (object_contents == DATA_OBJECT) { - maybe_result = heap->old_data_space()->AllocateRaw(allocation_size); + maybe_result = heap->old_data_space()->AllocateRaw(object_size); } else { - maybe_result = - heap->old_pointer_space()->AllocateRaw(allocation_size); + maybe_result = heap->old_pointer_space()->AllocateRaw(object_size); } } @@ -1728,10 +1642,6 @@ class ScavengingVisitor : public StaticVisitorBase { if (maybe_result->ToObject(&result)) { HeapObject* target = HeapObject::cast(result); - if (alignment != kObjectAlignment) { - target = EnsureDoubleAligned(heap, target, allocation_size); - } - // Order is important: slot might be inside of the target if target // was allocated over a dead object and slot comes from the store // buffer. @@ -1739,27 +1649,18 @@ class ScavengingVisitor : public StaticVisitorBase { MigrateObject(heap, object, target, object_size); if (object_contents == POINTER_OBJECT) { - if (map->instance_type() == JS_FUNCTION_TYPE) { - heap->promotion_queue()->insert( - target, JSFunction::kNonWeakFieldsEndOffset); - } else { - heap->promotion_queue()->insert(target, object_size); - } + heap->promotion_queue()->insert(target, object_size); } heap->tracer()->increment_promoted_objects_size(object_size); return; } } - MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size); + MaybeObject* allocation = heap->new_space()->AllocateRaw(object_size); heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); Object* result = allocation->ToObjectUnchecked(); HeapObject* target = HeapObject::cast(result); - if (alignment != kObjectAlignment) { - target = EnsureDoubleAligned(heap, target, allocation_size); - } - // Order is important: slot might be inside of the target if target // was allocated over a dead object and slot comes from the store // buffer. @@ -1795,7 +1696,7 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject** slot, HeapObject* object) { int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); - EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE, kObjectAlignment>(map, + EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); @@ -1807,11 +1708,10 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject* object) { int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); int object_size = FixedDoubleArray::SizeFor(length); - EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kDoubleAlignment>( - map, - slot, - object, - object_size); + EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, + slot, + object, + object_size); } @@ -1819,8 +1719,7 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject** slot, HeapObject* object) { int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); - EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); } @@ -1829,8 +1728,7 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject* object) { int object_size = SeqAsciiString::cast(object)-> SeqAsciiStringSize(map->instance_type()); - EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); } @@ -1839,8 +1737,7 @@ class ScavengingVisitor : public StaticVisitorBase { HeapObject* object) { int object_size = SeqTwoByteString::cast(object)-> SeqTwoByteStringSize(map->instance_type()); - EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); } @@ -1883,8 +1780,7 @@ class ScavengingVisitor : public StaticVisitorBase { } int object_size = ConsString::kSize; - EvacuateObject<POINTER_OBJECT, SMALL, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size); } template<ObjectContents object_contents> @@ -1894,16 +1790,14 @@ class ScavengingVisitor : public StaticVisitorBase { static inline void VisitSpecialized(Map* map, HeapObject** slot, HeapObject* object) { - EvacuateObject<object_contents, SMALL, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); } static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { int object_size = map->instance_size(); - EvacuateObject<object_contents, SMALL, kObjectAlignment>( - map, slot, object, object_size); + EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); } }; @@ -3939,16 +3833,6 @@ MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, } -MaybeObject* Heap::AllocateJSModule() { - // Allocate a fresh map. Modules do not have a prototype. - Map* map; - MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize); - if (!maybe_map->To(&map)) return maybe_map; - // Allocate the object based on the map. - return AllocateJSObjectFromMap(map, TENURED); -} - - MaybeObject* Heap::AllocateJSArrayAndStorage( ElementsKind elements_kind, int length, @@ -4085,7 +3969,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { // Fill these accessors into the dictionary. DescriptorArray* descs = map->instance_descriptors(); for (int i = 0; i < descs->number_of_descriptors(); i++) { - PropertyDetails details = descs->GetDetails(i); + PropertyDetails details(descs->GetDetails(i)); ASSERT(details.type() == CALLBACKS); // Only accessors are expected. PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, details.index()); @@ -4778,11 +4662,6 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; int size = FixedDoubleArray::SizeFor(length); - -#ifndef V8_HOST_ARCH_64_BIT - size += kPointerSize; -#endif - if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { // Too big for new space. space = LO_SPACE; @@ -4795,12 +4674,7 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, AllocationSpace retry_space = (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_DATA_SPACE : LO_SPACE; - HeapObject* object; - { MaybeObject* maybe_object = AllocateRaw(size, space, retry_space); - if (!maybe_object->To<HeapObject>(&object)) return maybe_object; - } - - return EnsureDoubleAligned(this, object, size); + return AllocateRaw(size, space, retry_space); } @@ -4833,22 +4707,6 @@ MaybeObject* Heap::AllocateGlobalContext() { } -MaybeObject* Heap::AllocateModuleContext(Context* previous, - ScopeInfo* scope_info) { - Object* result; - { MaybeObject* maybe_result = - AllocateFixedArrayWithHoles(scope_info->ContextLength(), TENURED); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - Context* context = reinterpret_cast<Context*>(result); - context->set_map_no_write_barrier(module_context_map()); - context->set_previous(previous); - context->set_extension(scope_info); - context->set_global(previous->global()); - return context; -} - - MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) { ASSERT(length >= Context::MIN_CONTEXT_SLOTS); Object* result; @@ -4991,10 +4849,8 @@ void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) { bool Heap::IdleNotification(int hint) { const int kMaxHint = 1000; - intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; - // The size factor is in range [5..250]. The numbers here are chosen from - // experiments. If you changes them, make sure to test with - // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* + intptr_t size_factor = Min(Max(hint, 30), kMaxHint) / 10; + // The size factor is in range [3..100]. intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; if (contexts_disposed_ > 0) { @@ -5018,14 +4874,11 @@ bool Heap::IdleNotification(int hint) { // Take into account that we might have decided to delay full collection // because incremental marking is in progress. ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); - // After context disposal there is likely a lot of garbage remaining, reset - // the idle notification counters in order to trigger more incremental GCs - // on subsequent idle notifications. - StartIdleRound(); return false; } - if (!FLAG_incremental_marking || FLAG_expose_gc || Serializer::enabled()) { + if (hint >= kMaxHint || !FLAG_incremental_marking || + FLAG_expose_gc || Serializer::enabled()) { return IdleGlobalGC(); } @@ -5064,6 +4917,10 @@ bool Heap::IdleNotification(int hint) { } if (incremental_marking()->IsStopped()) { + if (!WorthStartingGCWhenIdle()) { + FinishIdleRound(); + return true; + } incremental_marking()->Start(); } @@ -5701,11 +5558,6 @@ bool Heap::ConfigureHeap(int max_semispace_size, intptr_t max_executable_size) { if (HasBeenSetUp()) return false; - if (FLAG_stress_compaction) { - // This will cause more frequent GCs when stressing. - max_semispace_size_ = Page::kPageSize; - } - if (max_semispace_size > 0) { if (max_semispace_size < Page::kPageSize) { max_semispace_size = Page::kPageSize; @@ -5830,7 +5682,7 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() { } -intptr_t Heap::PromotedExternalMemorySize() { +int Heap::PromotedExternalMemorySize() { if (amount_of_external_allocated_memory_ <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; return amount_of_external_allocated_memory_ @@ -6003,15 +5855,6 @@ class HeapDebugUtils { #endif - -V8_DECLARE_ONCE(initialize_gc_once); - -static void InitializeGCOnce() { - InitializeScavengingVisitorsTables(); - NewSpaceScavenger::Initialize(); - MarkCompactCollector::Initialize(); -} - bool Heap::SetUp(bool create_heap_objects) { #ifdef DEBUG allocation_timeout_ = FLAG_gc_interval; @@ -6030,7 +5873,15 @@ bool Heap::SetUp(bool create_heap_objects) { if (!ConfigureHeapDefault()) return false; } - CallOnce(&initialize_gc_once, &InitializeGCOnce); + gc_initializer_mutex.Pointer()->Lock(); + static bool initialized_gc = false; + if (!initialized_gc) { + initialized_gc = true; + InitializeScavengingVisitorsTables(); + NewSpaceScavenger::Initialize(); + MarkCompactCollector::Initialize(); + } + gc_initializer_mutex.Pointer()->Unlock(); MarkMapPointersAsEncoded(false); @@ -6142,11 +5993,6 @@ void Heap::SetStackLimits() { void Heap::TearDown() { -#ifdef DEBUG - if (FLAG_verify_heap) { - Verify(); - } -#endif if (FLAG_print_cumulative_gc_stat) { PrintF("\n\n"); PrintF("gc_count=%d ", gc_count_); diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h index b91416fb08..0391e0e526 100644 --- a/deps/v8/src/heap.h +++ b/deps/v8/src/heap.h @@ -243,8 +243,7 @@ namespace internal { V(compare_ic_symbol, ".compare_ic") \ V(infinity_symbol, "Infinity") \ V(minus_infinity_symbol, "-Infinity") \ - V(hidden_stack_trace_symbol, "v8::hidden_stack_trace") \ - V(query_colon_symbol, "(?:)") + V(hidden_stack_trace_symbol, "v8::hidden_stack_trace") // Forward declarations. class GCTracer; @@ -530,8 +529,6 @@ class Heap { MUST_USE_RESULT MaybeObject* AllocateJSObject( JSFunction* constructor, PretenureFlag pretenure = NOT_TENURED); - MUST_USE_RESULT MaybeObject* AllocateJSModule(); - // Allocate a JSArray with no elements MUST_USE_RESULT MaybeObject* AllocateEmptyJSArray( ElementsKind elements_kind, @@ -823,10 +820,6 @@ class Heap { // Allocate a global (but otherwise uninitialized) context. MUST_USE_RESULT MaybeObject* AllocateGlobalContext(); - // Allocate a module context. - MUST_USE_RESULT MaybeObject* AllocateModuleContext(Context* previous, - ScopeInfo* scope_info); - // Allocate a function context. MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length, JSFunction* function); @@ -1333,8 +1326,7 @@ class Heap { // Adjusts the amount of registered external memory. // Returns the adjusted value. - inline intptr_t AdjustAmountOfExternalAllocatedMemory( - intptr_t change_in_bytes); + inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes); // Allocate uninitialized fixed array. MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length); @@ -1419,12 +1411,6 @@ class Heap { kRootListLength }; - STATIC_CHECK(kUndefinedValueRootIndex == Internals::kUndefinedValueRootIndex); - STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex); - STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex); - STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex); - STATIC_CHECK(kempty_symbolRootIndex == Internals::kEmptySymbolRootIndex); - MUST_USE_RESULT MaybeObject* NumberToString( Object* number, bool check_number_string_cache = true); MUST_USE_RESULT MaybeObject* Uint32ToString( @@ -1456,8 +1442,6 @@ class Heap { inline bool NextGCIsLikelyToBeFull() { if (FLAG_gc_global) return true; - if (FLAG_stress_compaction && (gc_count_ & 1) != 0) return true; - intptr_t total_promoted = PromotedTotalSize(); intptr_t adjusted_promotion_limit = @@ -1621,8 +1605,6 @@ class Heap { // more expedient to get at the isolate directly from within Heap methods. Isolate* isolate_; - Object* roots_[kRootListLength]; - intptr_t code_range_size_; int reserved_semispace_size_; int max_semispace_size_; @@ -1664,7 +1646,7 @@ class Heap { int gc_post_processing_depth_; // Returns the amount of external memory registered since last global gc. - intptr_t PromotedExternalMemorySize(); + int PromotedExternalMemorySize(); int ms_count_; // how many mark-sweep collections happened unsigned int gc_count_; // how many gc happened @@ -1729,15 +1711,17 @@ class Heap { // The amount of external memory registered through the API kept alive // by global handles - intptr_t amount_of_external_allocated_memory_; + int amount_of_external_allocated_memory_; // Caches the amount of external memory registered at the last global gc. - intptr_t amount_of_external_allocated_memory_at_last_global_gc_; + int amount_of_external_allocated_memory_at_last_global_gc_; // Indicates that an allocation has failed in the old generation since the // last GC. int old_gen_exhausted_; + Object* roots_[kRootListLength]; + Object* global_contexts_list_; StoreBufferRebuilder store_buffer_rebuilder_; @@ -1990,6 +1974,13 @@ class Heap { return (scavenges_since_last_idle_round_ >= kIdleScavengeThreshold); } + bool WorthStartingGCWhenIdle() { + if (contexts_disposed_ > 0) { + return true; + } + return incremental_marking()->WorthActivating(); + } + // Estimates how many milliseconds a Mark-Sweep would take to complete. // In idle notification handler we assume that this function will return: // - a number less than 10 for small heaps, which are less than 8Mb. diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index f8c021c2a8..f698da46d4 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -416,7 +416,6 @@ void HValue::Kill() { SetFlag(kIsDead); for (int i = 0; i < OperandCount(); ++i) { HValue* operand = OperandAt(i); - if (operand == NULL) continue; HUseListNode* first = operand->use_list_; if (first != NULL && first->value() == this && first->index() == i) { operand->use_list_ = first->tail(); @@ -463,8 +462,7 @@ void HValue::PrintChangesTo(StringStream* stream) { add_comma = true; \ stream->Add(#type); \ } - GVN_TRACKED_FLAG_LIST(PRINT_DO); - GVN_UNTRACKED_FLAG_LIST(PRINT_DO); + GVN_FLAG_LIST(PRINT_DO); #undef PRINT_DO } stream->Add("]"); @@ -601,9 +599,6 @@ void HInstruction::InsertAfter(HInstruction* previous) { SetBlock(block); previous->next_ = this; if (next != NULL) next->previous_ = this; - if (block->last() == previous) { - block->set_last(this); - } } @@ -613,7 +608,6 @@ void HInstruction::Verify() { HBasicBlock* cur_block = block(); for (int i = 0; i < OperandCount(); ++i) { HValue* other_operand = OperandAt(i); - if (other_operand == NULL) continue; HBasicBlock* other_block = other_operand->block(); if (cur_block == other_block) { if (!other_operand->IsPhi()) { @@ -872,17 +866,6 @@ HValue* HBitwise::Canonicalize() { } -HValue* HBitNot::Canonicalize() { - // Optimize ~~x, a common pattern used for ToInt32(x). - if (value()->IsBitNot()) { - HValue* result = HBitNot::cast(value())->value(); - ASSERT(result->representation().IsInteger32()); - return result; - } - return this; -} - - HValue* HAdd::Canonicalize() { if (!representation().IsInteger32()) return this; if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); @@ -933,62 +916,6 @@ void HJSArrayLength::PrintDataTo(StringStream* stream) { } -HValue* HUnaryMathOperation::Canonicalize() { - if (op() == kMathFloor) { - // If the input is integer32 then we replace the floor instruction - // with its input. This happens before the representation changes are - // introduced. - if (value()->representation().IsInteger32()) return value(); - -#ifdef V8_TARGET_ARCH_ARM - if (value()->IsDiv() && (value()->UseCount() == 1)) { - // TODO(2038): Implement this optimization for non ARM architectures. - HDiv* hdiv = HDiv::cast(value()); - HValue* left = hdiv->left(); - HValue* right = hdiv->right(); - // Try to simplify left and right values of the division. - HValue* new_left = - LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(left); - HValue* new_right = - LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); - - // Return if left or right are not optimizable. - if ((new_left == NULL) || (new_right == NULL)) return this; - - // Insert the new values in the graph. - if (new_left->IsInstruction() && - !HInstruction::cast(new_left)->IsLinked()) { - HInstruction::cast(new_left)->InsertBefore(this); - } - if (new_right->IsInstruction() && - !HInstruction::cast(new_right)->IsLinked()) { - HInstruction::cast(new_right)->InsertBefore(this); - } - HMathFloorOfDiv* instr = new HMathFloorOfDiv(context(), - new_left, - new_right); - // Replace this HMathFloor instruction by the new HMathFloorOfDiv. - instr->InsertBefore(this); - ReplaceAllUsesWith(instr); - Kill(); - // We know the division had no other uses than this HMathFloor. Delete it. - // Also delete the arguments of the division if they are not used any - // more. - hdiv->DeleteAndReplaceWith(NULL); - ASSERT(left->IsChange() || left->IsConstant()); - ASSERT(right->IsChange() || right->IsConstant()); - if (left->HasNoUses()) left->DeleteAndReplaceWith(NULL); - if (right->HasNoUses()) right->DeleteAndReplaceWith(NULL); - - // Return NULL to remove this instruction from the graph. - return NULL; - } -#endif // V8_TARGET_ARCH_ARM - } - return this; -} - - HValue* HCheckInstanceType::Canonicalize() { if (check_ == IS_STRING && !value()->type().IsUninitialized() && @@ -1038,13 +965,16 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) { } -void HCheckMaps::PrintDataTo(StringStream* stream) { +void HCheckMap::PrintDataTo(StringStream* stream) { value()->PrintNameTo(stream); - stream->Add(" [%p", *map_set()->first()); - for (int i = 1; i < map_set()->length(); ++i) { - stream->Add(",%p", *map_set()->at(i)); + stream->Add(" %p", *map()); + if (mode() == REQUIRE_EXACT_MAP) { + stream->Add(" [EXACT]"); + } else if (!has_element_transitions_) { + stream->Add(" [EXACT*]"); + } else { + stream->Add(" [MATCH ELEMENTS]"); } - stream->Add("]"); } @@ -1806,9 +1736,6 @@ void HStoreNamedField::PrintDataTo(StringStream* stream) { stream->Add(" = "); value()->PrintNameTo(stream); stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); - if (NeedsWriteBarrier()) { - stream->Add(" (write-barrier)"); - } if (!transition().is_null()) { stream->Add(" (transition map %p)", *transition()); } @@ -1952,7 +1879,7 @@ HType HValue::CalculateInferredType() { } -HType HCheckMaps::CalculateInferredType() { +HType HCheckMap::CalculateInferredType() { return value()->type(); } @@ -2162,17 +2089,6 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) { } -bool HStoreKeyedFastDoubleElement::NeedsCanonicalization() { - // If value was loaded from unboxed double backing store or - // converted from an integer then we don't have to canonicalize it. - if (value()->IsLoadKeyedFastDoubleElement() || - (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) { - return false; - } - return true; -} - - #define H_CONSTANT_INT32(val) \ new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ Representation::Integer32()) @@ -2341,13 +2257,6 @@ void HIn::PrintDataTo(StringStream* stream) { } -void HBitwise::PrintDataTo(StringStream* stream) { - stream->Add(Token::Name(op_)); - stream->Add(" "); - HBitwiseBinaryOperation::PrintDataTo(stream); -} - - Representation HPhi::InferredRepresentation() { bool double_occurred = false; bool int32_occurred = false; diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h index 9d262fc811..b63e647e1c 100644 --- a/deps/v8/src/hydrogen-instructions.h +++ b/deps/v8/src/hydrogen-instructions.h @@ -85,7 +85,7 @@ class LChunkBuilder; V(Change) \ V(CheckFunction) \ V(CheckInstanceType) \ - V(CheckMaps) \ + V(CheckMap) \ V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ @@ -140,7 +140,6 @@ class LChunkBuilder; V(LoadNamedField) \ V(LoadNamedFieldPolymorphic) \ V(LoadNamedGeneric) \ - V(MathFloorOfDiv) \ V(Mod) \ V(Mul) \ V(ObjectLiteral) \ @@ -189,10 +188,7 @@ class LChunkBuilder; V(DateField) \ V(WrapReceiver) -#define GVN_TRACKED_FLAG_LIST(V) \ - V(NewSpacePromotion) - -#define GVN_UNTRACKED_FLAG_LIST(V) \ +#define GVN_FLAG_LIST(V) \ V(Calls) \ V(InobjectFields) \ V(BackingStoreFields) \ @@ -510,18 +506,14 @@ class HUseIterator BASE_EMBEDDED { // There must be one corresponding kDepends flag for every kChanges flag and // the order of the kChanges flags must be exactly the same as of the kDepends -// flags. All tracked flags should appear before untracked ones. +// flags. enum GVNFlag { // Declare global value numbering flags. #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, - GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) - GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) + GVN_FLAG_LIST(DECLARE_FLAG) #undef DECLARE_FLAG kAfterLastFlag, - kLastFlag = kAfterLastFlag - 1, -#define COUNT_FLAG(type) + 1 - kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) -#undef COUNT_FLAG + kLastFlag = kAfterLastFlag - 1 }; typedef EnumSet<GVNFlag> GVNFlagSet; @@ -538,10 +530,6 @@ class HValue: public ZoneObject { // implement DataEquals(), which will be used to determine if other // occurrences of the instruction are indeed the same. kUseGVN, - // Track instructions that are dominating side effects. If an instruction - // sets this flag, it must implement SetSideEffectDominator() and should - // indicate which side effects to track by setting GVN flags. - kTrackSideEffectDominators, kCanOverflow, kBailoutOnMinusZero, kCanBeDivByZero, @@ -556,12 +544,6 @@ class HValue: public ZoneObject { static const int kChangesToDependsFlagsLeftShift = 1; - static GVNFlag ChangesFlagFromInt(int x) { - return static_cast<GVNFlag>(x * 2); - } - static GVNFlag DependsOnFlagFromInt(int x) { - return static_cast<GVNFlag>(x * 2 + 1); - } static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) { return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift); } @@ -744,13 +726,6 @@ class HValue: public ZoneObject { virtual HType CalculateInferredType(); - // This function must be overridden for instructions which have the - // kTrackSideEffectDominators flag set, to track instructions that are - // dominating side effects. - virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { - UNREACHABLE(); - } - #ifdef DEBUG virtual void Verify() = 0; #endif @@ -781,8 +756,7 @@ class HValue: public ZoneObject { GVNFlagSet result; // Create changes mask. #define ADD_FLAG(type) result.Add(kDependsOn##type); - GVN_TRACKED_FLAG_LIST(ADD_FLAG) - GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) + GVN_FLAG_LIST(ADD_FLAG) #undef ADD_FLAG return result; } @@ -791,8 +765,7 @@ class HValue: public ZoneObject { GVNFlagSet result; // Create changes mask. #define ADD_FLAG(type) result.Add(kChanges##type); - GVN_TRACKED_FLAG_LIST(ADD_FLAG) - GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) + GVN_FLAG_LIST(ADD_FLAG) #undef ADD_FLAG return result; } @@ -808,7 +781,6 @@ class HValue: public ZoneObject { // an executing program (i.e. are not safe to repeat, move or remove); static GVNFlagSet AllObservableSideEffectsFlagSet() { GVNFlagSet result = AllChangesFlagSet(); - result.Remove(kChangesNewSpacePromotion); result.Remove(kChangesElementsKind); result.Remove(kChangesElementsPointer); result.Remove(kChangesMaps); @@ -1224,7 +1196,6 @@ class HChange: public HUnaryOperation { SetFlag(kUseGVN); if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined); if (is_truncating) SetFlag(kTruncatingToInt32); - if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); } virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); @@ -1350,7 +1321,6 @@ class HStackCheck: public HTemplateInstruction<1> { HStackCheck(HValue* context, Type type) : type_(type) { SetOperandAt(0, context); - SetGVNFlag(kChangesNewSpacePromotion); } HValue* context() { return OperandAt(0); } @@ -1384,15 +1354,13 @@ class HEnterInlined: public HTemplateInstruction<0> { FunctionLiteral* function, CallKind call_kind, bool is_construct, - Variable* arguments_var, - ZoneList<HValue*>* arguments_values) + Variable* arguments) : closure_(closure), arguments_count_(arguments_count), function_(function), call_kind_(call_kind), is_construct_(is_construct), - arguments_var_(arguments_var), - arguments_values_(arguments_values) { + arguments_(arguments) { } virtual void PrintDataTo(StringStream* stream); @@ -1407,8 +1375,7 @@ class HEnterInlined: public HTemplateInstruction<0> { return Representation::None(); } - Variable* arguments_var() { return arguments_var_; } - ZoneList<HValue*>* arguments_values() { return arguments_values_; } + Variable* arguments() { return arguments_; } DECLARE_CONCRETE_INSTRUCTION(EnterInlined) @@ -1418,28 +1385,19 @@ class HEnterInlined: public HTemplateInstruction<0> { FunctionLiteral* function_; CallKind call_kind_; bool is_construct_; - Variable* arguments_var_; - ZoneList<HValue*>* arguments_values_; + Variable* arguments_; }; class HLeaveInlined: public HTemplateInstruction<0> { public: - explicit HLeaveInlined(bool arguments_pushed) - : arguments_pushed_(arguments_pushed) { } + HLeaveInlined() {} virtual Representation RequiredInputRepresentation(int index) { return Representation::None(); } - bool arguments_pushed() { - return arguments_pushed_; - } - DECLARE_CONCRETE_INSTRUCTION(LeaveInlined) - - private: - bool arguments_pushed_; }; @@ -1647,26 +1605,14 @@ class HInvokeFunction: public HBinaryCall { : HBinaryCall(context, function, argument_count) { } - HInvokeFunction(HValue* context, - HValue* function, - Handle<JSFunction> known_function, - int argument_count) - : HBinaryCall(context, function, argument_count), - known_function_(known_function) { - } - virtual Representation RequiredInputRepresentation(int index) { return Representation::Tagged(); } HValue* context() { return first(); } HValue* function() { return second(); } - Handle<JSFunction> known_function() { return known_function_; } DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) - - private: - Handle<JSFunction> known_function_; }; @@ -1919,8 +1865,6 @@ class HBitNot: public HUnaryOperation { } virtual HType CalculateInferredType(); - virtual HValue* Canonicalize(); - DECLARE_CONCRETE_INSTRUCTION(BitNot) protected: @@ -1943,7 +1887,6 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { case kMathAbs: set_representation(Representation::Tagged()); SetFlag(kFlexibleRepresentation); - SetGVNFlag(kChangesNewSpacePromotion); break; case kMathSqrt: case kMathPowHalf: @@ -1952,7 +1895,6 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { case kMathCos: case kMathTan: set_representation(Representation::Double()); - SetGVNFlag(kChangesNewSpacePromotion); break; default: UNREACHABLE(); @@ -1993,7 +1935,15 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { } } - virtual HValue* Canonicalize(); + virtual HValue* Canonicalize() { + // If the input is integer32 then we replace the floor instruction + // with its inputs. This happens before the representation changes are + // introduced. + if (op() == kMathFloor) { + if (value()->representation().IsInteger32()) return value(); + } + return this; + } BuiltinFunctionId op() const { return op_; } const char* OpName() const; @@ -2053,9 +2003,14 @@ class HLoadExternalArrayPointer: public HUnaryOperation { }; -class HCheckMaps: public HTemplateInstruction<2> { +class HCheckMap: public HTemplateInstruction<2> { public: - HCheckMaps(HValue* value, Handle<Map> map, HValue* typecheck = NULL) { + HCheckMap(HValue* value, + Handle<Map> map, + HValue* typecheck = NULL, + CompareMapMode mode = REQUIRE_EXACT_MAP) + : map_(map), + mode_(mode) { SetOperandAt(0, value); // If callers don't depend on a typecheck, they can pass in NULL. In that // case we use a copy of the |value| argument as a dummy value. @@ -2063,49 +2018,14 @@ class HCheckMaps: public HTemplateInstruction<2> { set_representation(Representation::Tagged()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnMaps); - SetGVNFlag(kDependsOnElementsKind); - map_set()->Add(map); - } - HCheckMaps(HValue* value, SmallMapList* maps) { - SetOperandAt(0, value); - SetOperandAt(1, value); - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - SetGVNFlag(kDependsOnMaps); - SetGVNFlag(kDependsOnElementsKind); - for (int i = 0; i < maps->length(); i++) { - map_set()->Add(maps->at(i)); + // If the map to check doesn't have the untransitioned elements, it must not + // be hoisted above TransitionElements instructions. + if (mode == REQUIRE_EXACT_MAP || !map->has_fast_smi_only_elements()) { + SetGVNFlag(kDependsOnElementsKind); } - map_set()->Sort(); - } - - static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map) { - HCheckMaps* check_map = new HCheckMaps(object, map); - SmallMapList* map_set = check_map->map_set(); - - // If the map to check has the untransitioned elements, it can be hoisted - // above TransitionElements instructions. - if (map->has_fast_smi_only_elements()) { - check_map->ClearGVNFlag(kDependsOnElementsKind); - } - - Map* transitioned_fast_element_map = - map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL); - ASSERT(transitioned_fast_element_map == NULL || - map->elements_kind() != FAST_ELEMENTS); - if (transitioned_fast_element_map != NULL) { - map_set->Add(Handle<Map>(transitioned_fast_element_map)); - } - Map* transitioned_double_map = - map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL); - ASSERT(transitioned_double_map == NULL || - map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); - if (transitioned_double_map != NULL) { - map_set->Add(Handle<Map>(transitioned_double_map)); - } - map_set->Sort(); - - return check_map; + has_element_transitions_ = + map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL || + map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL; } virtual Representation RequiredInputRepresentation(int index) { @@ -2115,23 +2035,25 @@ class HCheckMaps: public HTemplateInstruction<2> { virtual HType CalculateInferredType(); HValue* value() { return OperandAt(0); } - SmallMapList* map_set() { return &map_set_; } + Handle<Map> map() const { return map_; } + CompareMapMode mode() const { return mode_; } - DECLARE_CONCRETE_INSTRUCTION(CheckMaps) + DECLARE_CONCRETE_INSTRUCTION(CheckMap) protected: virtual bool DataEquals(HValue* other) { - HCheckMaps* b = HCheckMaps::cast(other); - // Relies on the fact that map_set has been sorted before. - if (map_set()->length() != b->map_set()->length()) return false; - for (int i = 0; i < map_set()->length(); i++) { - if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false; - } - return true; + HCheckMap* b = HCheckMap::cast(other); + // Two CheckMaps instructions are DataEqual if their maps are identical and + // they have the same mode. The mode comparison can be ignored if the map + // has no elements transitions. + return map_.is_identical_to(b->map()) && + (b->mode() == mode() || !has_element_transitions_); } private: - SmallMapList map_set_; + bool has_element_transitions_; + Handle<Map> map_; + CompareMapMode mode_; }; @@ -2627,7 +2549,7 @@ class HApplyArguments: public HTemplateInstruction<4> { class HArgumentsElements: public HTemplateInstruction<0> { public: - explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) { + HArgumentsElements() { // The value produced by this instruction is a pointer into the stack // that looks as if it was a smi because of alignment. set_representation(Representation::Tagged()); @@ -2640,12 +2562,8 @@ class HArgumentsElements: public HTemplateInstruction<0> { return Representation::None(); } - bool from_inlined() const { return from_inlined_; } - protected: virtual bool DataEquals(HValue* other) { return true; } - - bool from_inlined_; }; @@ -2751,25 +2669,6 @@ class HBitwiseBinaryOperation: public HBinaryOperation { }; -class HMathFloorOfDiv: public HBinaryOperation { - public: - HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) - : HBinaryOperation(context, left, right) { - set_representation(Representation::Integer32()); - SetFlag(kUseGVN); - } - - virtual Representation RequiredInputRepresentation(int index) { - return Representation::Integer32(); - } - - DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) - - protected: - virtual bool DataEquals(HValue* other) { return true; } -}; - - class HArithmeticBinaryOperation: public HBinaryOperation { public: HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) @@ -3184,7 +3083,6 @@ class HPower: public HTemplateInstruction<2> { SetOperandAt(1, right); set_representation(Representation::Double()); SetFlag(kUseGVN); - SetGVNFlag(kChangesNewSpacePromotion); } HValue* left() { return OperandAt(0); } @@ -3384,8 +3282,6 @@ class HBitwise: public HBitwiseBinaryOperation { HValue* left, HValue* right); - virtual void PrintDataTo(StringStream* stream); - DECLARE_CONCRETE_INSTRUCTION(Bitwise) protected: @@ -3633,12 +3529,6 @@ inline bool StoringValueNeedsWriteBarrier(HValue* value) { } -inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, - HValue* new_space_dominator) { - return !object->IsAllocateObject() || (object != new_space_dominator); -} - - class HStoreGlobalCell: public HUnaryOperation { public: HStoreGlobalCell(HValue* value, @@ -4105,12 +3995,9 @@ class HStoreNamedField: public HTemplateInstruction<2> { int offset) : name_(name), is_in_object_(in_object), - offset_(offset), - new_space_dominator_(NULL) { + offset_(offset) { SetOperandAt(0, obj); SetOperandAt(1, val); - SetFlag(kTrackSideEffectDominators); - SetGVNFlag(kDependsOnNewSpacePromotion); if (is_in_object_) { SetGVNFlag(kChangesInobjectFields); } else { @@ -4123,10 +4010,6 @@ class HStoreNamedField: public HTemplateInstruction<2> { virtual Representation RequiredInputRepresentation(int index) { return Representation::Tagged(); } - virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { - ASSERT(side_effect == kChangesNewSpacePromotion); - new_space_dominator_ = dominator; - } virtual void PrintDataTo(StringStream* stream); HValue* object() { return OperandAt(0); } @@ -4137,11 +4020,9 @@ class HStoreNamedField: public HTemplateInstruction<2> { int offset() const { return offset_; } Handle<Map> transition() const { return transition_; } void set_transition(Handle<Map> map) { transition_ = map; } - HValue* new_space_dominator() const { return new_space_dominator_; } bool NeedsWriteBarrier() { - return StoringValueNeedsWriteBarrier(value()) && - ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); + return StoringValueNeedsWriteBarrier(value()); } private: @@ -4149,7 +4030,6 @@ class HStoreNamedField: public HTemplateInstruction<2> { bool is_in_object_; int offset_; Handle<Map> transition_; - HValue* new_space_dominator_; }; @@ -4259,8 +4139,6 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { return StoringValueNeedsWriteBarrier(value()); } - bool NeedsCanonicalization(); - virtual void PrintDataTo(StringStream* stream); DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) @@ -4354,7 +4232,6 @@ class HTransitionElementsKind: public HTemplateInstruction<1> { SetFlag(kUseGVN); SetGVNFlag(kChangesElementsKind); SetGVNFlag(kChangesElementsPointer); - SetGVNFlag(kChangesNewSpacePromotion); set_representation(Representation::Tagged()); } @@ -4416,7 +4293,6 @@ class HStringCharCodeAt: public HTemplateInstruction<3> { set_representation(Representation::Integer32()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnMaps); - SetGVNFlag(kChangesNewSpacePromotion); } virtual Representation RequiredInputRepresentation(int index) { @@ -4448,7 +4324,6 @@ class HStringCharFromCode: public HTemplateInstruction<2> { SetOperandAt(1, char_code); set_representation(Representation::Tagged()); SetFlag(kUseGVN); - SetGVNFlag(kChangesNewSpacePromotion); } virtual Representation RequiredInputRepresentation(int index) { @@ -4501,12 +4376,8 @@ class HAllocateObject: public HTemplateInstruction<1> { : constructor_(constructor) { SetOperandAt(0, context); set_representation(Representation::Tagged()); - SetGVNFlag(kChangesNewSpacePromotion); } - // Maximum instance size for which allocations will be inlined. - static const int kMaxSize = 64 * kPointerSize; - HValue* context() { return OperandAt(0); } Handle<JSFunction> constructor() { return constructor_; } @@ -4550,7 +4421,6 @@ class HFastLiteral: public HMaterializedLiteral<1> { boilerplate_(boilerplate), total_size_(total_size) { SetOperandAt(0, context); - SetGVNFlag(kChangesNewSpacePromotion); } // Maximum depth and total number of elements and properties for literal @@ -4586,7 +4456,6 @@ class HArrayLiteral: public HMaterializedLiteral<1> { length_(length), boilerplate_object_(boilerplate_object) { SetOperandAt(0, context); - SetGVNFlag(kChangesNewSpacePromotion); } HValue* context() { return OperandAt(0); } @@ -4627,7 +4496,6 @@ class HObjectLiteral: public HMaterializedLiteral<1> { fast_elements_(fast_elements), has_function_(has_function) { SetOperandAt(0, context); - SetGVNFlag(kChangesNewSpacePromotion); } HValue* context() { return OperandAt(0); } @@ -4689,7 +4557,6 @@ class HFunctionLiteral: public HTemplateInstruction<1> { : shared_info_(shared), pretenure_(pretenure) { SetOperandAt(0, context); set_representation(Representation::Tagged()); - SetGVNFlag(kChangesNewSpacePromotion); } HValue* context() { return OperandAt(0); } diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc index b722f9f821..fd7560a372 100644 --- a/deps/v8/src/hydrogen.cc +++ b/deps/v8/src/hydrogen.cc @@ -113,6 +113,7 @@ void HBasicBlock::AddInstruction(HInstruction* instr) { first_ = last_ = entry; } instr->InsertAfter(last_); + last_ = instr; } @@ -164,15 +165,11 @@ void HBasicBlock::Finish(HControlInstruction* end) { } -void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { - bool drop_extra = state != NULL && state->drop_extra(); - bool arguments_pushed = state != NULL && state->arguments_pushed(); - +void HBasicBlock::Goto(HBasicBlock* block, bool drop_extra) { if (block->IsInlineReturnTarget()) { - AddInstruction(new(zone()) HLeaveInlined(arguments_pushed)); + AddInstruction(new(zone()) HLeaveInlined); last_environment_ = last_environment()->DiscardInlined(drop_extra); } - AddSimulate(AstNode::kNoNumber); HGoto* instr = new(zone()) HGoto(block); Finish(instr); @@ -181,13 +178,10 @@ void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { void HBasicBlock::AddLeaveInlined(HValue* return_value, HBasicBlock* target, - FunctionState* state) { - bool drop_extra = state != NULL && state->drop_extra(); - bool arguments_pushed = state != NULL && state->arguments_pushed(); - + bool drop_extra) { ASSERT(target->IsInlineReturnTarget()); ASSERT(return_value != NULL); - AddInstruction(new(zone()) HLeaveInlined(arguments_pushed)); + AddInstruction(new(zone()) HLeaveInlined); last_environment_ = last_environment()->DiscardInlined(drop_extra); last_environment()->Push(return_value); AddSimulate(AstNode::kNoNumber); @@ -612,7 +606,6 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info, graph_(NULL), current_block_(NULL), inlined_count_(0), - globals_(10), zone_(info->isolate()->zone()), inline_bailout_(false) { // This is not initialized in the initializer list because the @@ -1150,38 +1143,13 @@ void HRangeAnalysis::AddRange(HValue* value, Range* range) { void TraceGVN(const char* msg, ...) { - va_list arguments; - va_start(arguments, msg); - OS::VPrint(msg, arguments); - va_end(arguments); -} - -// Wrap TraceGVN in macros to avoid the expense of evaluating its arguments when -// --trace-gvn is off. -#define TRACE_GVN_1(msg, a1) \ - if (FLAG_trace_gvn) { \ - TraceGVN(msg, a1); \ - } - -#define TRACE_GVN_2(msg, a1, a2) \ - if (FLAG_trace_gvn) { \ - TraceGVN(msg, a1, a2); \ - } - -#define TRACE_GVN_3(msg, a1, a2, a3) \ - if (FLAG_trace_gvn) { \ - TraceGVN(msg, a1, a2, a3); \ - } - -#define TRACE_GVN_4(msg, a1, a2, a3, a4) \ - if (FLAG_trace_gvn) { \ - TraceGVN(msg, a1, a2, a3, a4); \ - } - -#define TRACE_GVN_5(msg, a1, a2, a3, a4, a5) \ - if (FLAG_trace_gvn) { \ - TraceGVN(msg, a1, a2, a3, a4, a5); \ + if (FLAG_trace_gvn) { + va_list arguments; + va_start(arguments, msg); + OS::VPrint(msg, arguments); + va_end(arguments); } +} HValueMap::HValueMap(Zone* zone, const HValueMap* other) @@ -1353,38 +1321,6 @@ void HValueMap::Insert(HValue* value) { } -HSideEffectMap::HSideEffectMap() : count_(0) { - memset(data_, 0, kNumberOfTrackedSideEffects * kPointerSize); -} - - -HSideEffectMap::HSideEffectMap(HSideEffectMap* other) : count_(other->count_) { - memcpy(data_, other->data_, kNumberOfTrackedSideEffects * kPointerSize); -} - - -void HSideEffectMap::Kill(GVNFlagSet flags) { - for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { - GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); - if (flags.Contains(changes_flag)) { - if (data_[i] != NULL) count_--; - data_[i] = NULL; - } - } -} - - -void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) { - for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { - GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); - if (flags.Contains(changes_flag)) { - if (data_[i] == NULL) count_++; - data_[i] = instr; - } - } -} - - class HStackCheckEliminator BASE_EMBEDDED { public: explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { } @@ -1491,9 +1427,7 @@ class HGlobalValueNumberer BASE_EMBEDDED { GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( HBasicBlock* dominator, HBasicBlock* dominated); - void AnalyzeBlock(HBasicBlock* block, - HValueMap* map, - HSideEffectMap* dominators); + void AnalyzeBlock(HBasicBlock* block, HValueMap* map); void ComputeBlockSideEffects(); void LoopInvariantCodeMotion(); void ProcessLoopBlock(HBasicBlock* block, @@ -1531,8 +1465,7 @@ bool HGlobalValueNumberer::Analyze() { LoopInvariantCodeMotion(); } HValueMap* map = new(zone()) HValueMap(); - HSideEffectMap side_effect_dominators; - AnalyzeBlock(graph_->entry_block(), map, &side_effect_dominators); + AnalyzeBlock(graph_->entry_block(), map); return removed_side_effects_; } @@ -1577,100 +1510,14 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() { } -SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) { - char underlying_buffer[kLastFlag * 128]; - Vector<char> buffer(underlying_buffer, sizeof(underlying_buffer)); -#if DEBUG - int offset = 0; - const char* separator = ""; - const char* comma = ", "; - buffer[0] = 0; - uint32_t set_depends_on = 0; - uint32_t set_changes = 0; - for (int bit = 0; bit < kLastFlag; ++bit) { - if ((flags.ToIntegral() & (1 << bit)) != 0) { - if (bit % 2 == 0) { - set_changes++; - } else { - set_depends_on++; - } - } - } - bool positive_changes = set_changes < (kLastFlag / 2); - bool positive_depends_on = set_depends_on < (kLastFlag / 2); - if (set_changes > 0) { - if (positive_changes) { - offset += OS::SNPrintF(buffer + offset, "changes ["); - } else { - offset += OS::SNPrintF(buffer + offset, "changes all except ["); - } - for (int bit = 0; bit < kLastFlag; ++bit) { - if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_changes) { - switch (static_cast<GVNFlag>(bit)) { -#define DECLARE_FLAG(type) \ - case kChanges##type: \ - offset += OS::SNPrintF(buffer + offset, separator); \ - offset += OS::SNPrintF(buffer + offset, #type); \ - separator = comma; \ - break; -GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) -GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) -#undef DECLARE_FLAG - default: - break; - } - } - } - offset += OS::SNPrintF(buffer + offset, "]"); - } - if (set_depends_on > 0) { - separator = ""; - if (set_changes > 0) { - offset += OS::SNPrintF(buffer + offset, ", "); - } - if (positive_depends_on) { - offset += OS::SNPrintF(buffer + offset, "depends on ["); - } else { - offset += OS::SNPrintF(buffer + offset, "depends on all except ["); - } - for (int bit = 0; bit < kLastFlag; ++bit) { - if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_depends_on) { - switch (static_cast<GVNFlag>(bit)) { -#define DECLARE_FLAG(type) \ - case kDependsOn##type: \ - offset += OS::SNPrintF(buffer + offset, separator); \ - offset += OS::SNPrintF(buffer + offset, #type); \ - separator = comma; \ - break; -GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) -GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) -#undef DECLARE_FLAG - default: - break; - } - } - } - offset += OS::SNPrintF(buffer + offset, "]"); - } -#else - OS::SNPrintF(buffer, "0x%08X", flags.ToIntegral()); -#endif - size_t string_len = strlen(underlying_buffer) + 1; - ASSERT(string_len <= sizeof(underlying_buffer)); - char* result = new char[strlen(underlying_buffer) + 1]; - memcpy(result, underlying_buffer, string_len); - return SmartArrayPointer<char>(result); -} - - void HGlobalValueNumberer::LoopInvariantCodeMotion() { for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { HBasicBlock* block = graph_->blocks()->at(i); if (block->IsLoopHeader()) { GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; - TRACE_GVN_2("Try loop invariant motion for block B%d %s\n", - block->block_id(), - *GetGVNFlagsString(side_effects)); + TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", + block->block_id(), + side_effects.ToIntegral()); GVNFlagSet accumulated_first_time_depends; GVNFlagSet accumulated_first_time_changes; @@ -1693,19 +1540,20 @@ void HGlobalValueNumberer::ProcessLoopBlock( GVNFlagSet* first_time_changes) { HBasicBlock* pre_header = loop_header->predecessors()->at(0); GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); - TRACE_GVN_2("Loop invariant motion for B%d %s\n", - block->block_id(), - *GetGVNFlagsString(depends_flags)); + TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", + block->block_id(), + depends_flags.ToIntegral()); HInstruction* instr = block->first(); while (instr != NULL) { HInstruction* next = instr->next(); bool hoisted = false; if (instr->CheckFlag(HValue::kUseGVN)) { - TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n", - instr->id(), - instr->Mnemonic(), - *GetGVNFlagsString(instr->gvn_flags()), - *GetGVNFlagsString(loop_kills)); + TraceGVN("Checking instruction %d (%s) instruction GVN flags 0x%X, " + "loop kills 0x%X\n", + instr->id(), + instr->Mnemonic(), + instr->gvn_flags().ToIntegral(), + depends_flags.ToIntegral()); bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); if (instr->IsTransitionElementsKind()) { // It's possible to hoist transitions out of a loop as long as the @@ -1728,19 +1576,15 @@ void HGlobalValueNumberer::ProcessLoopBlock( if (trans->transitioned_map()->has_fast_double_elements()) { hoist_change_blockers.Add(kChangesArrayElements); } - if (FLAG_trace_gvn) { - GVNFlagSet hoist_blockers = hoist_depends_blockers; - hoist_blockers.Add(hoist_change_blockers); - GVNFlagSet first_time = *first_time_changes; - first_time.Add(*first_time_depends); - TRACE_GVN_4("Checking dependencies on HTransitionElementsKind " - "%d (%s) hoist blockers: %s; " - "first-time accumulated: %s\n", - instr->id(), - instr->Mnemonic(), - *GetGVNFlagsString(hoist_blockers), - *GetGVNFlagsString(first_time)); - } + TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) " + "hoist depends blockers 0x%X, hoist change blockers 0x%X, " + "accumulated depends 0x%X, accumulated changes 0x%X\n", + instr->id(), + instr->Mnemonic(), + hoist_depends_blockers.ToIntegral(), + hoist_change_blockers.ToIntegral(), + first_time_depends->ToIntegral(), + first_time_changes->ToIntegral()); // It's possible to hoist transition from the current loop loop only if // they dominate all of the successor blocks in the same loop and there // are not any instructions that have Changes/DependsOn that intervene @@ -1763,7 +1607,7 @@ void HGlobalValueNumberer::ProcessLoopBlock( } if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { - TRACE_GVN_1("Hoisting loop invariant instruction %d\n", instr->id()); + TraceGVN("Hoisting loop invariant instruction %d\n", instr->id()); // Move the instruction out of the loop. instr->Unlink(); instr->InsertBefore(pre_header->end()); @@ -1775,18 +1619,8 @@ void HGlobalValueNumberer::ProcessLoopBlock( if (!hoisted) { // If an instruction is not hoisted, we have to account for its side // effects when hoisting later HTransitionElementsKind instructions. - GVNFlagSet previous_depends = *first_time_depends; - GVNFlagSet previous_changes = *first_time_changes; first_time_depends->Add(instr->DependsOnFlags()); first_time_changes->Add(instr->ChangesFlags()); - if (!(previous_depends == *first_time_depends)) { - TRACE_GVN_1("Updated first-time accumulated %s\n", - *GetGVNFlagsString(*first_time_depends)); - } - if (!(previous_changes == *first_time_changes)) { - TRACE_GVN_1("Updated first-time accumulated %s\n", - *GetGVNFlagsString(*first_time_changes)); - } } instr = next; } @@ -1826,12 +1660,10 @@ GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( } -void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, - HValueMap* map, - HSideEffectMap* dominators) { - TRACE_GVN_2("Analyzing block B%d%s\n", - block->block_id(), - block->IsLoopHeader() ? " (loop header)" : ""); +void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { + TraceGVN("Analyzing block B%d%s\n", + block->block_id(), + block->IsLoopHeader() ? " (loop header)" : ""); // If this is a loop header kill everything killed by the loop. if (block->IsLoopHeader()) { @@ -1845,45 +1677,25 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, GVNFlagSet flags = instr->ChangesFlags(); if (!flags.IsEmpty()) { // Clear all instructions in the map that are affected by side effects. - // Store instruction as the dominating one for tracked side effects. map->Kill(flags); - dominators->Store(flags, instr); - TRACE_GVN_2("Instruction %d %s\n", instr->id(), - *GetGVNFlagsString(flags)); + TraceGVN("Instruction %d kills\n", instr->id()); } if (instr->CheckFlag(HValue::kUseGVN)) { ASSERT(!instr->HasObservableSideEffects()); HValue* other = map->Lookup(instr); if (other != NULL) { ASSERT(instr->Equals(other) && other->Equals(instr)); - TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", - instr->id(), - instr->Mnemonic(), - other->id(), - other->Mnemonic()); + TraceGVN("Replacing value %d (%s) with value %d (%s)\n", + instr->id(), + instr->Mnemonic(), + other->id(), + other->Mnemonic()); if (instr->HasSideEffects()) removed_side_effects_ = true; instr->DeleteAndReplaceWith(other); } else { map->Add(instr); } } - if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { - for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { - HValue* other = dominators->at(i); - GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); - GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); - if (instr->DependsOnFlags().Contains(depends_on_flag) && - (other != NULL)) { - TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", - i, - instr->id(), - instr->Mnemonic(), - other->id(), - other->Mnemonic()); - instr->SetSideEffectDominator(changes_flag, other); - } - } - } instr = next; } @@ -1893,22 +1705,20 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HBasicBlock* dominated = block->dominated_blocks()->at(i); // No need to copy the map for the last child in the dominator tree. HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone()); - HSideEffectMap successor_dominators(dominators); // Kill everything killed on any path between this block and the - // dominated block. We don't have to traverse these paths if the - // value map and the dominators list is already empty. If the range - // of block ids (block_id, dominated_id) is empty there are no such - // paths. - if ((!successor_map->IsEmpty() || !successor_dominators.IsEmpty()) && + // dominated block. + // We don't have to traverse these paths if the value map is + // already empty. + // If the range of block ids (block_id, dominated_id) is empty + // there are no such paths. + if (!successor_map->IsEmpty() && block->block_id() + 1 < dominated->block_id()) { visited_on_paths_.Clear(); - GVNFlagSet side_effects_on_all_paths = - CollectSideEffectsOnPathsToDominatedBlock(block, dominated); - successor_map->Kill(side_effects_on_all_paths); - successor_dominators.Kill(side_effects_on_all_paths); + successor_map->Kill(CollectSideEffectsOnPathsToDominatedBlock(block, + dominated)); } - AnalyzeBlock(dominated, successor_map, &successor_dominators); + AnalyzeBlock(dominated, successor_map); } } @@ -2368,8 +2178,6 @@ FunctionState::FunctionState(HGraphBuilder* owner, return_handling_(return_handling), function_return_(NULL), test_context_(NULL), - entry_(NULL), - arguments_elements_(NULL), outer_(owner->function_state()) { if (outer_ != NULL) { // State for an inline function. @@ -2529,8 +2337,8 @@ void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { instr->SetSuccessorAt(0, empty_true); instr->SetSuccessorAt(1, empty_false); owner()->current_block()->Finish(instr); - empty_true->Goto(if_true(), owner()->function_state()); - empty_false->Goto(if_false(), owner()->function_state()); + empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); + empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); owner()->set_current_block(NULL); } @@ -2551,8 +2359,8 @@ void TestContext::BuildBranch(HValue* value) { HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); builder->current_block()->Finish(test); - empty_true->Goto(if_true(), owner()->function_state()); - empty_false->Goto(if_false(), owner()->function_state()); + empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); + empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); builder->set_current_block(NULL); } @@ -2676,7 +2484,7 @@ HGraph* HGraphBuilder::CreateGraph() { // Handle implicit declaration of the function name in named function // expressions before other declarations. if (scope->is_function_scope() && scope->function() != NULL) { - VisitVariableDeclaration(scope->function()); + HandleDeclaration(scope->function(), CONST, NULL, NULL); } VisitDeclarations(scope->declarations()); AddSimulate(AstNode::kDeclarationsId); @@ -2757,331 +2565,32 @@ HGraph* HGraphBuilder::CreateGraph() { HStackCheckEliminator sce(graph()); sce.Process(); - graph()->EliminateRedundantBoundsChecks(); + // Replace the results of check instructions with the original value, if the + // result is used. This is safe now, since we don't do code motion after this + // point. It enables better register allocation since the value produced by + // check instructions is really a copy of the original value. + graph()->ReplaceCheckedValues(); return graph(); } -// We try to "factor up" HBoundsCheck instructions towards the root of the -// dominator tree. -// For now we handle checks where the index is like "exp + int32value". -// If in the dominator tree we check "exp + v1" and later (dominated) -// "exp + v2", if v2 <= v1 we can safely remove the second check, and if -// v2 > v1 we can use v2 in the 1st check and again remove the second. -// To do so we keep a dictionary of all checks where the key if the pair -// "exp, length". -// The class BoundsCheckKey represents this key. -class BoundsCheckKey : public ZoneObject { - public: - HValue* IndexBase() const { return index_base_; } - HValue* Length() const { return length_; } - - uint32_t Hash() { - return static_cast<uint32_t>(index_base_->Hashcode() ^ length_->Hashcode()); - } - - static BoundsCheckKey* Create(Zone* zone, - HBoundsCheck* check, - int32_t* offset) { - HValue* index_base = NULL; - HConstant* constant = NULL; - bool is_sub = false; - - if (check->index()->IsAdd()) { - HAdd* index = HAdd::cast(check->index()); - if (index->left()->IsConstant()) { - constant = HConstant::cast(index->left()); - index_base = index->right(); - } else if (index->right()->IsConstant()) { - constant = HConstant::cast(index->right()); - index_base = index->left(); - } - } else if (check->index()->IsSub()) { - HSub* index = HSub::cast(check->index()); - is_sub = true; - if (index->left()->IsConstant()) { - constant = HConstant::cast(index->left()); - index_base = index->right(); - } else if (index->right()->IsConstant()) { - constant = HConstant::cast(index->right()); - index_base = index->left(); +void HGraph::ReplaceCheckedValues() { + HPhase phase("H_Replace checked values", this); + for (int i = 0; i < blocks()->length(); ++i) { + HInstruction* instr = blocks()->at(i)->first(); + while (instr != NULL) { + if (instr->IsBoundsCheck()) { + // Replace all uses of the checked value with the original input. + ASSERT(instr->UseCount() > 0); + instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index()); } - } - - if (constant != NULL && constant->HasInteger32Value()) { - *offset = is_sub ? - constant->Integer32Value() - : constant->Integer32Value(); - } else { - *offset = 0; - index_base = check->index(); - } - - return new(zone) BoundsCheckKey(index_base, check->length()); - } - - private: - BoundsCheckKey(HValue* index_base, HValue* length) - : index_base_(index_base), - length_(length) { } - - HValue* index_base_; - HValue* length_; -}; - - -// Data about each HBoundsCheck that can be eliminated or moved. -// It is the "value" in the dictionary indexed by "base-index, length" -// (the key is BoundsCheckKey). -// We scan the code with a dominator tree traversal. -// Traversing the dominator tree we keep a stack (implemented as a singly -// linked list) of "data" for each basic block that contains a relevant check -// with the same key (the dictionary holds the head of the list). -// We also keep all the "data" created for a given basic block in a list, and -// use it to "clean up" the dictionary when backtracking in the dominator tree -// traversal. -// Doing this each dictionary entry always directly points to the check that -// is dominating the code being examined now. -// We also track the current "offset" of the index expression and use it to -// decide if any check is already "covered" (so it can be removed) or not. -class BoundsCheckBbData: public ZoneObject { - public: - BoundsCheckKey* Key() const { return key_; } - int32_t LowerOffset() const { return lower_offset_; } - int32_t UpperOffset() const { return upper_offset_; } - HBasicBlock* BasicBlock() const { return basic_block_; } - HBoundsCheck* Check() const { return check_; } - BoundsCheckBbData* NextInBasicBlock() const { return next_in_bb_; } - BoundsCheckBbData* FatherInDominatorTree() const { return father_in_dt_; } - - bool OffsetIsCovered(int32_t offset) const { - return offset >= LowerOffset() && offset <= UpperOffset(); - } - - // This method removes new_check and modifies the current check so that it - // also "covers" what new_check covered. - // The obvious precondition is that new_check follows Check() in the - // same basic block, and that new_offset is not covered (otherwise we - // could simply remove new_check). - // As a consequence LowerOffset() or UpperOffset() change (the covered - // range grows). - // - // In the general case the check covering the current range should be like - // these two checks: - // 0 <= Key()->IndexBase() + LowerOffset() - // Key()->IndexBase() + UpperOffset() < Key()->Length() - // - // We can transform the second check like this: - // Key()->IndexBase() + LowerOffset() < - // Key()->Length() + (LowerOffset() - UpperOffset()) - // so we can handle both checks with a single unsigned comparison. - // - // The bulk of this method changes Check()->index() and Check()->length() - // replacing them with new HAdd instructions to perform the transformation - // described above. - void CoverCheck(HBoundsCheck* new_check, - int32_t new_offset) { - ASSERT(new_check->index()->representation().IsInteger32()); - - if (new_offset > upper_offset_) { - upper_offset_ = new_offset; - } else if (new_offset < lower_offset_) { - lower_offset_ = new_offset; - } else { - ASSERT(false); - } - - BuildOffsetAdd(&added_index_, - &added_index_offset_, - Key()->IndexBase(), - new_check->index()->representation(), - lower_offset_); - Check()->SetOperandAt(0, added_index_); - BuildOffsetAdd(&added_length_, - &added_length_offset_, - Key()->Length(), - new_check->length()->representation(), - lower_offset_ - upper_offset_); - Check()->SetOperandAt(1, added_length_); - - new_check->DeleteAndReplaceWith(NULL); - } - - void RemoveZeroOperations() { - RemoveZeroAdd(&added_index_, &added_index_offset_); - RemoveZeroAdd(&added_length_, &added_length_offset_); - } - - BoundsCheckBbData(BoundsCheckKey* key, - int32_t lower_offset, - int32_t upper_offset, - HBasicBlock* bb, - HBoundsCheck* check, - BoundsCheckBbData* next_in_bb, - BoundsCheckBbData* father_in_dt) - : key_(key), - lower_offset_(lower_offset), - upper_offset_(upper_offset), - basic_block_(bb), - check_(check), - added_index_offset_(NULL), - added_index_(NULL), - added_length_offset_(NULL), - added_length_(NULL), - next_in_bb_(next_in_bb), - father_in_dt_(father_in_dt) { } - - private: - BoundsCheckKey* key_; - int32_t lower_offset_; - int32_t upper_offset_; - HBasicBlock* basic_block_; - HBoundsCheck* check_; - HConstant* added_index_offset_; - HAdd* added_index_; - HConstant* added_length_offset_; - HAdd* added_length_; - BoundsCheckBbData* next_in_bb_; - BoundsCheckBbData* father_in_dt_; - - void BuildOffsetAdd(HAdd** add, - HConstant** constant, - HValue* original_value, - Representation representation, - int32_t new_offset) { - HConstant* new_constant = new(BasicBlock()->zone()) - HConstant(Handle<Object>(Smi::FromInt(new_offset)), - Representation::Integer32()); - if (*add == NULL) { - new_constant->InsertBefore(Check()); - *add = new(BasicBlock()->zone()) HAdd(NULL, - original_value, - new_constant); - (*add)->AssumeRepresentation(representation); - (*add)->InsertBefore(Check()); - } else { - new_constant->InsertBefore(*add); - (*constant)->DeleteAndReplaceWith(new_constant); - } - *constant = new_constant; - } - - void RemoveZeroAdd(HAdd** add, HConstant** constant) { - if (*add != NULL && (*constant)->Integer32Value() == 0) { - (*add)->DeleteAndReplaceWith((*add)->left()); - (*constant)->DeleteAndReplaceWith(NULL); - } - } -}; - - -static bool BoundsCheckKeyMatch(void* key1, void* key2) { - BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); - BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); - return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); -} - - -class BoundsCheckTable : private ZoneHashMap { - public: - BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { - return reinterpret_cast<BoundsCheckBbData**>( - &(Lookup(key, key->Hash(), true)->value)); - } - - void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { - Lookup(key, key->Hash(), true)->value = data; - } - - void Delete(BoundsCheckKey* key) { - Remove(key, key->Hash()); - } - - BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } -}; - - -// Eliminates checks in bb and recursively in the dominated blocks. -// Also replace the results of check instructions with the original value, if -// the result is used. This is safe now, since we don't do code motion after -// this point. It enables better register allocation since the value produced -// by check instructions is really a copy of the original value. -void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, - BoundsCheckTable* table) { - BoundsCheckBbData* bb_data_list = NULL; - - for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { - if (!i->IsBoundsCheck()) continue; - - HBoundsCheck* check = HBoundsCheck::cast(i); - check->ReplaceAllUsesWith(check->index()); - - isolate()->counters()->array_bounds_checks_seen()->Increment(); - if (!FLAG_array_bounds_checks_elimination) continue; - - int32_t offset; - BoundsCheckKey* key = - BoundsCheckKey::Create(bb->zone(), check, &offset); - BoundsCheckBbData** data_p = table->LookupOrInsert(key); - BoundsCheckBbData* data = *data_p; - if (data == NULL) { - bb_data_list = new(zone()) BoundsCheckBbData(key, - offset, - offset, - bb, - check, - bb_data_list, - NULL); - *data_p = bb_data_list; - } else if (data->OffsetIsCovered(offset)) { - check->DeleteAndReplaceWith(NULL); - isolate()->counters()->array_bounds_checks_removed()->Increment(); - } else if (data->BasicBlock() == bb) { - data->CoverCheck(check, offset); - isolate()->counters()->array_bounds_checks_removed()->Increment(); - } else { - int32_t new_lower_offset = offset < data->LowerOffset() - ? offset - : data->LowerOffset(); - int32_t new_upper_offset = offset > data->UpperOffset() - ? offset - : data->UpperOffset(); - bb_data_list = new(bb->zone()) BoundsCheckBbData(key, - new_lower_offset, - new_upper_offset, - bb, - check, - bb_data_list, - data); - table->Insert(key, bb_data_list); - } - } - - for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { - EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); - } - - for (BoundsCheckBbData* data = bb_data_list; - data != NULL; - data = data->NextInBasicBlock()) { - data->RemoveZeroOperations(); - if (data->FatherInDominatorTree()) { - table->Insert(data->Key(), data->FatherInDominatorTree()); - } else { - table->Delete(data->Key()); + instr = instr->next(); } } } -void HGraph::EliminateRedundantBoundsChecks() { - HPhase phase("H_Eliminate bounds checks", this); - AssertNoAllocation no_gc; - BoundsCheckTable checks_table; - EliminateRedundantBoundsChecks(entry_block(), &checks_table); -} - - HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { ASSERT(current_block() != NULL); current_block()->AddInstruction(instr); @@ -3192,7 +2701,7 @@ void HGraphBuilder::VisitBlock(Block* stmt) { ASSERT(!HasStackOverflow()); ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); - if (stmt->scope() != NULL) { + if (stmt->block_scope() != NULL) { return Bailout("ScopedBlock"); } BreakAndContinueInfo break_info(stmt); @@ -3346,10 +2855,10 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { if (context->IsTest()) { TestContext* test = TestContext::cast(context); CHECK_ALIVE(VisitForEffect(stmt->expression())); - current_block()->Goto(test->if_true(), function_state()); + current_block()->Goto(test->if_true(), function_state()->drop_extra()); } else if (context->IsEffect()) { CHECK_ALIVE(VisitForEffect(stmt->expression())); - current_block()->Goto(function_return(), function_state()); + current_block()->Goto(function_return(), function_state()->drop_extra()); } else { ASSERT(context->IsValue()); CHECK_ALIVE(VisitForValue(stmt->expression())); @@ -3366,10 +2875,10 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { current_block()->Finish(typecheck); if_spec_object->AddLeaveInlined(return_value, function_return(), - function_state()); + function_state()->drop_extra()); not_spec_object->AddLeaveInlined(receiver, function_return(), - function_state()); + function_state()->drop_extra()); } } else { // Return from an inlined function, visit the subexpression in the @@ -3381,14 +2890,14 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { test->if_false()); } else if (context->IsEffect()) { CHECK_ALIVE(VisitForEffect(stmt->expression())); - current_block()->Goto(function_return(), function_state()); + current_block()->Goto(function_return(), function_state()->drop_extra()); } else { ASSERT(context->IsValue()); CHECK_ALIVE(VisitForValue(stmt->expression())); HValue* return_value = Pop(); current_block()->AddLeaveInlined(return_value, function_return(), - function_state()); + function_state()->drop_extra()); } } set_current_block(NULL); @@ -4173,11 +3682,10 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate, if (boilerplate->HasFastDoubleElements()) { *total_size += FixedDoubleArray::SizeFor(elements->length()); } else if (boilerplate->HasFastElements()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); int length = elements->length(); for (int i = 0; i < length; i++) { if ((*max_properties)-- == 0) return false; - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(boilerplate, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); if (!IsFastLiteral(value_object, @@ -4406,22 +3914,21 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { } -// Sets the lookup result and returns true if the load/store can be inlined. -static bool ComputeLoadStoreField(Handle<Map> type, - Handle<String> name, - LookupResult* lookup, - bool is_store) { +// Sets the lookup result and returns true if the store can be inlined. +static bool ComputeStoredField(Handle<Map> type, + Handle<String> name, + LookupResult* lookup) { type->LookupInDescriptors(NULL, *name, lookup); if (!lookup->IsFound()) return false; if (lookup->type() == FIELD) return true; - return is_store && (lookup->type() == MAP_TRANSITION) && + return (lookup->type() == MAP_TRANSITION) && (type->unused_property_fields() > 0); } -static int ComputeLoadStoreFieldIndex(Handle<Map> type, - Handle<String> name, - LookupResult* lookup) { +static int ComputeStoredFieldIndex(Handle<Map> type, + Handle<String> name, + LookupResult* lookup) { ASSERT(lookup->type() == FIELD || lookup->type() == MAP_TRANSITION); if (lookup->type() == FIELD) { return lookup->GetLocalFieldIndexFromMap(*type); @@ -4440,10 +3947,11 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, bool smi_and_map_check) { if (smi_and_map_check) { AddInstruction(new(zone()) HCheckNonSmi(object)); - AddInstruction(HCheckMaps::NewWithTransitions(object, type)); + AddInstruction(new(zone()) HCheckMap(object, type, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); } - int index = ComputeLoadStoreFieldIndex(type, name, lookup); + int index = ComputeStoredFieldIndex(type, name, lookup); bool is_in_object = index < 0; int offset = index * kPointerSize; if (index < 0) { @@ -4489,7 +3997,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, LookupResult lookup(isolate()); Handle<Map> type = prop->GetReceiverType(); bool is_monomorphic = prop->IsMonomorphic() && - ComputeLoadStoreField(type, name, &lookup, true); + ComputeStoredField(type, name, &lookup); return is_monomorphic ? BuildStoreNamedField(object, name, value, type, &lookup, @@ -4511,7 +4019,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, LookupResult lookup(isolate()); SmallMapList* types = expr->GetReceiverTypes(); bool is_monomorphic = expr->IsMonomorphic() && - ComputeLoadStoreField(types->first(), name, &lookup, true); + ComputeStoredField(types->first(), name, &lookup); return is_monomorphic ? BuildStoreNamedField(object, name, value, types->first(), &lookup, @@ -4520,59 +4028,6 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, } -void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, - HValue* object, - SmallMapList* types, - Handle<String> name) { - int count = 0; - int previous_field_offset = 0; - bool previous_field_is_in_object = false; - bool is_monomorphic_field = true; - Handle<Map> map; - LookupResult lookup(isolate()); - for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { - map = types->at(i); - if (ComputeLoadStoreField(map, name, &lookup, false)) { - int index = ComputeLoadStoreFieldIndex(map, name, &lookup); - bool is_in_object = index < 0; - int offset = index * kPointerSize; - if (index < 0) { - // Negative property indices are in-object properties, indexed - // from the end of the fixed part of the object. - offset += map->instance_size(); - } else { - offset += FixedArray::kHeaderSize; - } - if (count == 0) { - previous_field_offset = offset; - previous_field_is_in_object = is_in_object; - } else if (is_monomorphic_field) { - is_monomorphic_field = (offset == previous_field_offset) && - (is_in_object == previous_field_is_in_object); - } - ++count; - } - } - - // Use monomorphic load if property lookup results in the same field index - // for all maps. Requires special map check on the set of all handled maps. - HInstruction* instr; - if (count == types->length() && is_monomorphic_field) { - AddInstruction(new(zone()) HCheckMaps(object, types)); - instr = BuildLoadNamedField(object, expr, map, &lookup, false); - } else { - HValue* context = environment()->LookupContext(); - instr = new(zone()) HLoadNamedFieldPolymorphic(context, - object, - types, - name); - } - - instr->set_position(expr->position()); - return ast_context()->ReturnInstruction(instr, expr->id()); -} - - void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, HValue* object, HValue* value, @@ -4586,7 +4041,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { Handle<Map> map = types->at(i); LookupResult lookup(isolate()); - if (ComputeLoadStoreField(map, name, &lookup, true)) { + if (ComputeStoredField(map, name, &lookup)) { if (count == 0) { AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. join = graph()->CreateBasicBlock(); @@ -5057,7 +4512,8 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, bool smi_and_map_check) { if (smi_and_map_check) { AddInstruction(new(zone()) HCheckNonSmi(object)); - AddInstruction(HCheckMaps::NewWithTransitions(object, type)); + AddInstruction(new(zone()) HCheckMap(object, type, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); } int index = lookup->GetLocalFieldIndexFromMap(*type); @@ -5101,7 +4557,8 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, true); } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { AddInstruction(new(zone()) HCheckNonSmi(obj)); - AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); + AddInstruction(new(zone()) HCheckMap(obj, map, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); return new(zone()) HConstant(function, Representation::Tagged()); } else { @@ -5203,12 +4660,12 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, HValue* val, Handle<Map> map, bool is_store) { - HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMaps(object, map)); + HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); bool fast_smi_only_elements = map->has_fast_smi_only_elements(); bool fast_elements = map->has_fast_elements(); HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); if (is_store && (fast_elements || fast_smi_only_elements)) { - AddInstruction(new(zone()) HCheckMaps( + AddInstruction(new(zone()) HCheckMap( elements, isolate()->factory()->fixed_array_map())); } HInstruction* length = NULL; @@ -5358,7 +4815,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, elements_kind == FAST_ELEMENTS || elements_kind == FAST_DOUBLE_ELEMENTS) { if (is_store && elements_kind != FAST_DOUBLE_ELEMENTS) { - AddInstruction(new(zone()) HCheckMaps( + AddInstruction(new(zone()) HCheckMap( elements, isolate()->factory()->fixed_array_map(), elements_kind_branch)); } @@ -5476,34 +4933,6 @@ HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, function_strict_mode_flag()); } - -void HGraphBuilder::EnsureArgumentsArePushedForAccess() { - // Outermost function already has arguments on the stack. - if (function_state()->outer() == NULL) return; - - if (function_state()->arguments_pushed()) return; - - // Push arguments when entering inlined function. - HEnterInlined* entry = function_state()->entry(); - - ZoneList<HValue*>* arguments_values = entry->arguments_values(); - - HInstruction* insert_after = entry; - for (int i = 0; i < arguments_values->length(); i++) { - HValue* argument = arguments_values->at(i); - HInstruction* push_argument = new(zone()) HPushArgument(argument); - push_argument->InsertAfter(insert_after); - insert_after = push_argument; - } - - HArgumentsElements* arguments_elements = - new(zone()) HArgumentsElements(true); - arguments_elements->ClearFlag(HValue::kUseGVN); - arguments_elements->InsertAfter(insert_after); - function_state()->set_arguments_elements(arguments_elements); -} - - bool HGraphBuilder::TryArgumentsAccess(Property* expr) { VariableProxy* proxy = expr->obj()->AsVariableProxy(); if (proxy == NULL) return false; @@ -5512,51 +4941,31 @@ bool HGraphBuilder::TryArgumentsAccess(Property* expr) { return false; } + // Our implementation of arguments (based on this stack frame or an + // adapter below it) does not work for inlined functions. + if (function_state()->outer() != NULL) { + Bailout("arguments access in inlined function"); + return true; + } + HInstruction* result = NULL; if (expr->key()->IsPropertyName()) { Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); if (!name->IsEqualTo(CStrVector("length"))) return false; - - if (function_state()->outer() == NULL) { - HInstruction* elements = AddInstruction( - new(zone()) HArgumentsElements(false)); - result = new(zone()) HArgumentsLength(elements); - } else { - // Number of arguments without receiver. - int argument_count = environment()-> - arguments_environment()->parameter_count() - 1; - result = new(zone()) HConstant( - Handle<Object>(Smi::FromInt(argument_count)), - Representation::Integer32()); - } + HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); + result = new(zone()) HArgumentsLength(elements); } else { Push(graph()->GetArgumentsObject()); VisitForValue(expr->key()); if (HasStackOverflow() || current_block() == NULL) return true; HValue* key = Pop(); Drop(1); // Arguments object. - if (function_state()->outer() == NULL) { - HInstruction* elements = AddInstruction( - new(zone()) HArgumentsElements(false)); - HInstruction* length = AddInstruction( - new(zone()) HArgumentsLength(elements)); - HInstruction* checked_key = - AddInstruction(new(zone()) HBoundsCheck(key, length)); - result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); - } else { - EnsureArgumentsArePushedForAccess(); - - // Number of arguments without receiver. - HInstruction* elements = function_state()->arguments_elements(); - int argument_count = environment()-> - arguments_environment()->parameter_count() - 1; - HInstruction* length = AddInstruction(new(zone()) HConstant( - Handle<Object>(Smi::FromInt(argument_count)), - Representation::Integer32())); - HInstruction* checked_key = - AddInstruction(new(zone()) HBoundsCheck(key, length)); - result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); - } + HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); + HInstruction* length = AddInstruction( + new(zone()) HArgumentsLength(elements)); + HInstruction* checked_key = + AddInstruction(new(zone()) HBoundsCheck(key, length)); + result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); } ast_context()->ReturnInstruction(result, expr->id()); return true; @@ -5610,8 +5019,8 @@ void HGraphBuilder::VisitProperty(Property* expr) { instr = BuildLoadNamed(obj, expr, types->first(), name); } else if (types != NULL && types->length() > 1) { AddInstruction(new(zone()) HCheckNonSmi(obj)); - HandlePolymorphicLoadNamedField(expr, obj, types, name); - return; + HValue* context = environment()->LookupContext(); + instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); } else { instr = BuildLoadNamedGeneric(obj, expr); } @@ -5652,7 +5061,8 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr, // its prototypes. if (smi_and_map_check) { AddInstruction(new(zone()) HCheckNonSmi(receiver)); - AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); + AddInstruction(new(zone()) HCheckMap(receiver, receiver_map, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); } if (!expr->holder().is_null()) { AddInstruction(new(zone()) HCheckPrototypeMaps( @@ -5779,8 +5189,8 @@ bool HGraphBuilder::TryInline(CallKind call_kind, // Do a quick check on source code length to avoid parsing large // inlining candidates. - if (target_shared->SourceSize() > - Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { + if ((FLAG_limit_inlining && target_shared->SourceSize() > kMaxSourceSize) + || target_shared->SourceSize() > kUnlimitedMaxSourceSize) { TraceInline(target, caller, "target text too big"); return false; } @@ -5796,7 +5206,8 @@ bool HGraphBuilder::TryInline(CallKind call_kind, } int nodes_added = target_shared->ast_node_count(); - if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { + if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || + nodes_added > kUnlimitedMaxInlinedSize) { TraceInline(target, caller, "target AST is too large [early]"); return false; } @@ -5838,8 +5249,8 @@ bool HGraphBuilder::TryInline(CallKind call_kind, } // We don't want to add more than a certain number of nodes from inlining. - if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative, - kUnlimitedMaxInlinedNodesCumulative)) { + if ((FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) || + inlined_count_ > kUnlimitedMaxInlinedNodes) { TraceInline(target, caller, "cumulative AST node limit reached"); return false; } @@ -5866,7 +5277,8 @@ bool HGraphBuilder::TryInline(CallKind call_kind, // The following conditions must be checked again after re-parsing, because // earlier the information might not have been complete due to lazy parsing. nodes_added = function->ast_node_count(); - if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { + if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) || + nodes_added > kUnlimitedMaxInlinedSize) { TraceInline(target, caller, "target AST is too large [late]"); return false; } @@ -5961,42 +5373,20 @@ bool HGraphBuilder::TryInline(CallKind call_kind, AddInstruction(context); inner_env->BindContext(context); #endif - AddSimulate(return_id); current_block()->UpdateEnvironment(inner_env); - - ZoneList<HValue*>* arguments_values = NULL; - - // If the function uses arguments copy current arguments values - // to use them for materialization. - if (function->scope()->arguments() != NULL) { - HEnvironment* arguments_env = inner_env->arguments_environment(); - int arguments_count = arguments_env->parameter_count(); - arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); - for (int i = 0; i < arguments_count; i++) { - arguments_values->Add(arguments_env->Lookup(i)); - } - } - - HEnterInlined* enter_inlined = - new(zone()) HEnterInlined(target, - arguments->length(), - function, - call_kind, - function_state()->is_construct(), - function->scope()->arguments(), - arguments_values); - function_state()->set_entry(enter_inlined); - AddInstruction(enter_inlined); - + AddInstruction(new(zone()) HEnterInlined(target, + arguments->length(), + function, + call_kind, + function_state()->is_construct(), + function->scope()->arguments())); // If the function uses arguments object create and bind one. if (function->scope()->arguments() != NULL) { ASSERT(function->scope()->arguments()->IsStackAllocated()); - inner_env->Bind(function->scope()->arguments(), - graph()->GetArgumentsObject()); + environment()->Bind(function->scope()->arguments(), + graph()->GetArgumentsObject()); } - - VisitDeclarations(target_info.scope()->declarations()); VisitStatements(function->body()); if (HasStackOverflow()) { @@ -6025,17 +5415,17 @@ bool HGraphBuilder::TryInline(CallKind call_kind, : undefined; current_block()->AddLeaveInlined(return_value, function_return(), - function_state()); + function_state()->drop_extra()); } else if (call_context()->IsEffect()) { ASSERT(function_return() != NULL); - current_block()->Goto(function_return(), function_state()); + current_block()->Goto(function_return(), function_state()->drop_extra()); } else { ASSERT(call_context()->IsTest()); ASSERT(inlined_test_context() != NULL); HBasicBlock* target = function_state()->is_construct() ? inlined_test_context()->if_true() : inlined_test_context()->if_false(); - current_block()->Goto(target, function_state()); + current_block()->Goto(target, function_state()->drop_extra()); } } @@ -6053,12 +5443,12 @@ bool HGraphBuilder::TryInline(CallKind call_kind, if (if_true->HasPredecessor()) { if_true->SetJoinId(ast_id); HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); - if_true->Goto(true_target, function_state()); + if_true->Goto(true_target, function_state()->drop_extra()); } if (if_false->HasPredecessor()) { if_false->SetJoinId(ast_id); HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); - if_false->Goto(false_target, function_state()); + if_false->Goto(false_target, function_state()->drop_extra()); } set_current_block(NULL); return true; @@ -6367,8 +5757,7 @@ bool HGraphBuilder::TryCallApply(Call* expr) { HValue* receiver = Pop(); if (function_state()->outer() == NULL) { - HInstruction* elements = AddInstruction( - new(zone()) HArgumentsElements(false)); + HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); HValue* wrapped_receiver = @@ -6587,11 +5976,9 @@ void HGraphBuilder::VisitCall(Call* expr) { if (TryInlineCall(expr, true)) { // Drop function from environment. return; } else { - call = PreProcessCall( - new(zone()) HInvokeFunction(context, - function, - expr->target(), - argument_count)); + call = PreProcessCall(new(zone()) HInvokeFunction(context, + function, + argument_count)); Drop(1); // The function. } @@ -6619,8 +6006,7 @@ void HGraphBuilder::VisitCall(Call* expr) { // Checks whether allocation using the given constructor can be inlined. static bool IsAllocationInlineable(Handle<JSFunction> constructor) { return constructor->has_initial_map() && - constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && - constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; + constructor->initial_map()->instance_type() == JS_OBJECT_TYPE; } @@ -7512,9 +6898,11 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { Handle<Map> map = oracle()->GetCompareMap(expr); if (!map.is_null()) { AddInstruction(new(zone()) HCheckNonSmi(left)); - AddInstruction(HCheckMaps::NewWithTransitions(left, map)); + AddInstruction(new(zone()) HCheckMap(left, map, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); AddInstruction(new(zone()) HCheckNonSmi(right)); - AddInstruction(HCheckMaps::NewWithTransitions(right, map)); + AddInstruction(new(zone()) HCheckMap(right, map, NULL, + ALLOW_ELEMENT_TRANSITION_MAPS)); HCompareObjectEqAndBranch* result = new(zone()) HCompareObjectEqAndBranch(left, right); result->set_position(expr->position()); @@ -7586,50 +6974,90 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) { - ASSERT(globals_.is_empty()); - AstVisitor::VisitDeclarations(declarations); - if (!globals_.is_empty()) { + int length = declarations->length(); + int global_count = 0; + for (int i = 0; i < declarations->length(); i++) { + Declaration* decl = declarations->at(i); + FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration(); + HandleDeclaration(decl->proxy(), + decl->mode(), + fun_decl != NULL ? fun_decl->fun() : NULL, + &global_count); + } + + // Batch declare global functions and variables. + if (global_count > 0) { Handle<FixedArray> array = - isolate()->factory()->NewFixedArray(globals_.length(), TENURED); - for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); + isolate()->factory()->NewFixedArray(2 * global_count, TENURED); + for (int j = 0, i = 0; i < length; i++) { + Declaration* decl = declarations->at(i); + Variable* var = decl->proxy()->var(); + + if (var->IsUnallocated()) { + array->set(j++, *(var->name())); + FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration(); + if (fun_decl == NULL) { + if (var->binding_needs_init()) { + // In case this binding needs initialization use the hole. + array->set_the_hole(j++); + } else { + array->set_undefined(j++); + } + } else { + Handle<SharedFunctionInfo> function = + Compiler::BuildFunctionInfo(fun_decl->fun(), info()->script()); + // Check for stack-overflow exception. + if (function.is_null()) { + SetStackOverflow(); + return; + } + array->set(j++, *function); + } + } + } int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | DeclareGlobalsNativeFlag::encode(info()->is_native()) | DeclareGlobalsLanguageMode::encode(info()->language_mode()); - HInstruction* result = new(zone()) HDeclareGlobals( - environment()->LookupContext(), array, flags); + HInstruction* result = + new(zone()) HDeclareGlobals(environment()->LookupContext(), + array, + flags); AddInstruction(result); - globals_.Clear(); } } -void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - VariableMode mode = declaration->mode(); - Variable* variable = proxy->var(); - bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; - switch (variable->location()) { +void HGraphBuilder::HandleDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function, + int* global_count) { + Variable* var = proxy->var(); + bool binding_needs_init = + (mode == CONST || mode == CONST_HARMONY || mode == LET); + switch (var->location()) { case Variable::UNALLOCATED: - globals_.Add(variable->name()); - globals_.Add(variable->binding_needs_init() - ? isolate()->factory()->the_hole_value() - : isolate()->factory()->undefined_value()); + ++(*global_count); return; case Variable::PARAMETER: case Variable::LOCAL: - if (hole_init) { - HValue* value = graph()->GetConstantHole(); - environment()->Bind(variable, value); - } - break; case Variable::CONTEXT: - if (hole_init) { - HValue* value = graph()->GetConstantHole(); - HValue* context = environment()->LookupContext(); - HStoreContextSlot* store = new HStoreContextSlot( - context, variable->index(), HStoreContextSlot::kNoCheck, value); - AddInstruction(store); - if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); + if (binding_needs_init || function != NULL) { + HValue* value = NULL; + if (function != NULL) { + CHECK_ALIVE(VisitForValue(function)); + value = Pop(); + } else { + value = graph()->GetConstantHole(); + } + if (var->IsContextSlot()) { + HValue* context = environment()->LookupContext(); + HStoreContextSlot* store = new HStoreContextSlot( + context, var->index(), HStoreContextSlot::kNoCheck, value); + AddInstruction(store); + if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); + } else { + environment()->Bind(var, value); + } } break; case Variable::LOOKUP: @@ -7638,74 +7066,48 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { } -void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: { - globals_.Add(variable->name()); - Handle<SharedFunctionInfo> function = - Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); - // Check for stack-overflow exception. - if (function.is_null()) return SetStackOverflow(); - globals_.Add(function); - return; - } - case Variable::PARAMETER: - case Variable::LOCAL: { - CHECK_ALIVE(VisitForValue(declaration->fun())); - HValue* value = Pop(); - environment()->Bind(variable, value); - break; - } - case Variable::CONTEXT: { - CHECK_ALIVE(VisitForValue(declaration->fun())); - HValue* value = Pop(); - HValue* context = environment()->LookupContext(); - HStoreContextSlot* store = new HStoreContextSlot( - context, variable->index(), HStoreContextSlot::kNoCheck, value); - AddInstruction(store); - if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); - break; - } - case Variable::LOOKUP: - return Bailout("unsupported lookup slot in declaration"); - } +void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { + UNREACHABLE(); } -void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { +void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { UNREACHABLE(); } -void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) { +void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) { UNREACHABLE(); } -void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* declaration) { +void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) { UNREACHABLE(); } -void HGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { +void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) { UNREACHABLE(); } +void HGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) { + // TODO(rossberg) +} + + void HGraphBuilder::VisitModuleVariable(ModuleVariable* module) { - UNREACHABLE(); + // TODO(rossberg) } void HGraphBuilder::VisitModulePath(ModulePath* module) { - UNREACHABLE(); + // TODO(rossberg) } void HGraphBuilder::VisitModuleUrl(ModuleUrl* module) { - UNREACHABLE(); + // TODO(rossberg) } @@ -7826,8 +7228,7 @@ void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { // function is blacklisted by AstNode::IsInlineable. ASSERT(function_state()->outer() == NULL); ASSERT(call->arguments()->length() == 0); - HInstruction* elements = AddInstruction( - new(zone()) HArgumentsElements(false)); + HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); HArgumentsLength* result = new(zone()) HArgumentsLength(elements); return ast_context()->ReturnInstruction(result, call->id()); } @@ -7841,8 +7242,7 @@ void HGraphBuilder::GenerateArguments(CallRuntime* call) { ASSERT(call->arguments()->length() == 1); CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); HValue* index = Pop(); - HInstruction* elements = AddInstruction( - new(zone()) HArgumentsElements(false)); + HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); HAccessArgumentsAt* result = new(zone()) HAccessArgumentsAt(elements, length, index); diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h index a52bf3baad..e2779bb226 100644 --- a/deps/v8/src/hydrogen.h +++ b/deps/v8/src/hydrogen.h @@ -42,7 +42,6 @@ namespace internal { // Forward declarations. class BitVector; -class FunctionState; class HEnvironment; class HGraph; class HLoopInformation; @@ -122,7 +121,7 @@ class HBasicBlock: public ZoneObject { void Finish(HControlInstruction* last); void FinishExit(HControlInstruction* instruction); - void Goto(HBasicBlock* block, FunctionState* state = NULL); + void Goto(HBasicBlock* block, bool drop_extra = false); int PredecessorIndexOf(HBasicBlock* predecessor) const; void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); } @@ -137,7 +136,7 @@ class HBasicBlock: public ZoneObject { // instruction and updating the bailout environment. void AddLeaveInlined(HValue* return_value, HBasicBlock* target, - FunctionState* state = NULL); + bool drop_extra = false); // If a target block is tagged as an inline function return, all // predecessors should contain the inlined exit sequence: @@ -241,7 +240,7 @@ class HLoopInformation: public ZoneObject { HStackCheck* stack_check_; }; -class BoundsCheckTable; + class HGraph: public ZoneObject { public: explicit HGraph(CompilationInfo* info); @@ -266,7 +265,6 @@ class HGraph: public ZoneObject { void OrderBlocks(); void AssignDominators(); void ReplaceCheckedValues(); - void EliminateRedundantBoundsChecks(); void PropagateDeoptimizingMark(); // Returns false if there are phi-uses of the arguments-object @@ -359,7 +357,6 @@ class HGraph: public ZoneObject { void InferTypes(ZoneList<HValue*>* worklist); void InitializeInferredTypes(int from_inclusive, int to_inclusive); void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor); - void EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table); Isolate* isolate_; int next_block_id_; @@ -718,16 +715,6 @@ class FunctionState { FunctionState* outer() { return outer_; } - HEnterInlined* entry() { return entry_; } - void set_entry(HEnterInlined* entry) { entry_ = entry; } - - HArgumentsElements* arguments_elements() { return arguments_elements_; } - void set_arguments_elements(HArgumentsElements* arguments_elements) { - arguments_elements_ = arguments_elements; - } - - bool arguments_pushed() { return arguments_elements() != NULL; } - private: HGraphBuilder* owner_; @@ -754,12 +741,6 @@ class FunctionState { // return blocks. NULL in all other cases. TestContext* test_context_; - // When inlining HEnterInlined instruction corresponding to the function - // entry. - HEnterInlined* entry_; - - HArgumentsElements* arguments_elements_; - FunctionState* outer_; }; @@ -870,11 +851,15 @@ class HGraphBuilder: public AstVisitor { static const int kMaxLoadPolymorphism = 4; static const int kMaxStorePolymorphism = 4; + static const int kMaxInlinedNodes = 196; + static const int kMaxInlinedSize = 196; + static const int kMaxSourceSize = 600; + // Even in the 'unlimited' case we have to have some limit in order not to // overflow the stack. - static const int kUnlimitedMaxInlinedSourceSize = 100000; - static const int kUnlimitedMaxInlinedNodes = 10000; - static const int kUnlimitedMaxInlinedNodesCumulative = 10000; + static const int kUnlimitedMaxInlinedNodes = 1000; + static const int kUnlimitedMaxInlinedSize = 1000; + static const int kUnlimitedMaxSourceSize = 600; // Simple accessors. void set_function_state(FunctionState* state) { function_state_ = state; } @@ -911,6 +896,11 @@ class HGraphBuilder: public AstVisitor { INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) #undef INLINE_FUNCTION_GENERATOR_DECLARATION + void HandleDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function, + int* global_count); + void VisitDelete(UnaryOperation* expr); void VisitVoid(UnaryOperation* expr); void VisitTypeof(UnaryOperation* expr); @@ -1004,7 +994,6 @@ class HGraphBuilder: public AstVisitor { LookupResult* lookup, bool is_store); - void EnsureArgumentsArePushedForAccess(); bool TryArgumentsAccess(Property* expr); // Try to optimize fun.apply(receiver, arguments) pattern. @@ -1040,10 +1029,6 @@ class HGraphBuilder: public AstVisitor { void HandlePropertyAssignment(Assignment* expr); void HandleCompoundAssignment(Assignment* expr); - void HandlePolymorphicLoadNamedField(Property* expr, - HValue* object, - SmallMapList* types, - Handle<String> name); void HandlePolymorphicStoreNamedField(Assignment* expr, HValue* object, HValue* value, @@ -1160,7 +1145,6 @@ class HGraphBuilder: public AstVisitor { HBasicBlock* current_block_; int inlined_count_; - ZoneList<Handle<Object> > globals_; Zone* zone_; @@ -1235,30 +1219,6 @@ class HValueMap: public ZoneObject { }; -class HSideEffectMap BASE_EMBEDDED { - public: - HSideEffectMap(); - explicit HSideEffectMap(HSideEffectMap* other); - - void Kill(GVNFlagSet flags); - - void Store(GVNFlagSet flags, HInstruction* instr); - - bool IsEmpty() const { return count_ == 0; } - - inline HInstruction* operator[](int i) const { - ASSERT(0 <= i); - ASSERT(i < kNumberOfTrackedSideEffects); - return data_[i]; - } - inline HInstruction* at(int i) const { return operator[](i); } - - private: - int count_; - HInstruction* data_[kNumberOfTrackedSideEffects]; -}; - - class HStatistics: public Malloced { public: void Initialize(CompilationInfo* info); diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc index a36763db20..a5d42cfbe4 100644 --- a/deps/v8/src/ia32/builtins-ia32.cc +++ b/deps/v8/src/ia32/builtins-ia32.cc @@ -831,7 +831,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Copy all arguments from the array to the stack. Label entry, loop; - __ mov(ecx, Operand(ebp, kIndexOffset)); + __ mov(eax, Operand(ebp, kIndexOffset)); __ jmp(&entry); __ bind(&loop); __ mov(edx, Operand(ebp, kArgumentsOffset)); // load arguments @@ -848,17 +848,16 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ push(eax); // Update the index on the stack and in register eax. - __ mov(ecx, Operand(ebp, kIndexOffset)); - __ add(ecx, Immediate(1 << kSmiTagSize)); - __ mov(Operand(ebp, kIndexOffset), ecx); + __ mov(eax, Operand(ebp, kIndexOffset)); + __ add(eax, Immediate(1 << kSmiTagSize)); + __ mov(Operand(ebp, kIndexOffset), eax); __ bind(&entry); - __ cmp(ecx, Operand(ebp, kLimitOffset)); + __ cmp(eax, Operand(ebp, kLimitOffset)); __ j(not_equal, &loop); // Invoke the function. Label call_proxy; - __ mov(eax, ecx); ParameterCount actual(eax); __ SmiUntag(eax); __ mov(edi, Operand(ebp, kFunctionOffset)); diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc index a1c6edd0fa..4faa6a4b24 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.cc +++ b/deps/v8/src/ia32/code-stubs-ia32.cc @@ -1681,11 +1681,6 @@ void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { } -// Input: -// edx: left operand (tagged) -// eax: right operand (tagged) -// Output: -// eax: result (tagged) void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { Label call_runtime; ASSERT(operands_type_ == BinaryOpIC::INT32); @@ -1695,37 +1690,31 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { case Token::ADD: case Token::SUB: case Token::MUL: - case Token::DIV: - case Token::MOD: { + case Token::DIV: { Label not_floats; Label not_int32; if (CpuFeatures::IsSupported(SSE2)) { CpuFeatures::Scope use_sse2(SSE2); FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, ¬_int32, ecx); - if (op_ == Token::MOD) { - GenerateRegisterArgsPush(masm); - __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); - } else { - switch (op_) { - case Token::ADD: __ addsd(xmm0, xmm1); break; - case Token::SUB: __ subsd(xmm0, xmm1); break; - case Token::MUL: __ mulsd(xmm0, xmm1); break; - case Token::DIV: __ divsd(xmm0, xmm1); break; - default: UNREACHABLE(); - } - // Check result type if it is currently Int32. - if (result_type_ <= BinaryOpIC::INT32) { - __ cvttsd2si(ecx, Operand(xmm0)); - __ cvtsi2sd(xmm2, ecx); - __ ucomisd(xmm0, xmm2); - __ j(not_zero, ¬_int32); - __ j(carry, ¬_int32); - } - GenerateHeapResultAllocation(masm, &call_runtime); - __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); - __ ret(0); + switch (op_) { + case Token::ADD: __ addsd(xmm0, xmm1); break; + case Token::SUB: __ subsd(xmm0, xmm1); break; + case Token::MUL: __ mulsd(xmm0, xmm1); break; + case Token::DIV: __ divsd(xmm0, xmm1); break; + default: UNREACHABLE(); } + // Check result type if it is currently Int32. + if (result_type_ <= BinaryOpIC::INT32) { + __ cvttsd2si(ecx, Operand(xmm0)); + __ cvtsi2sd(xmm2, ecx); + __ ucomisd(xmm0, xmm2); + __ j(not_zero, ¬_int32); + __ j(carry, ¬_int32); + } + GenerateHeapResultAllocation(masm, &call_runtime); + __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); + __ ret(0); } else { // SSE2 not available, use FPU. FloatingPointHelper::CheckFloatOperands(masm, ¬_floats, ebx); FloatingPointHelper::LoadFloatOperands( @@ -1733,28 +1722,20 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ecx, FloatingPointHelper::ARGS_IN_REGISTERS); FloatingPointHelper::CheckFloatOperandsAreInt32(masm, ¬_int32); - if (op_ == Token::MOD) { - // The operands are now on the FPU stack, but we don't need them. - __ fstp(0); - __ fstp(0); - GenerateRegisterArgsPush(masm); - __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); - } else { - switch (op_) { - case Token::ADD: __ faddp(1); break; - case Token::SUB: __ fsubp(1); break; - case Token::MUL: __ fmulp(1); break; - case Token::DIV: __ fdivp(1); break; - default: UNREACHABLE(); - } - Label after_alloc_failure; - GenerateHeapResultAllocation(masm, &after_alloc_failure); - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); - __ ret(0); - __ bind(&after_alloc_failure); - __ fstp(0); // Pop FPU stack before calling runtime. - __ jmp(&call_runtime); + switch (op_) { + case Token::ADD: __ faddp(1); break; + case Token::SUB: __ fsubp(1); break; + case Token::MUL: __ fmulp(1); break; + case Token::DIV: __ fdivp(1); break; + default: UNREACHABLE(); } + Label after_alloc_failure; + GenerateHeapResultAllocation(masm, &after_alloc_failure); + __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); + __ ret(0); + __ bind(&after_alloc_failure); + __ ffree(); + __ jmp(&call_runtime); } __ bind(¬_floats); @@ -1763,6 +1744,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { break; } + case Token::MOD: { + // For MOD we go directly to runtime in the non-smi case. + break; + } case Token::BIT_OR: case Token::BIT_AND: case Token::BIT_XOR: @@ -1773,6 +1758,11 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { Label not_floats; Label not_int32; Label non_smi_result; + /* { + CpuFeatures::Scope use_sse2(SSE2); + FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); + FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, ¬_int32, ecx); + }*/ FloatingPointHelper::LoadUnknownsAsIntegers(masm, use_sse3_, ¬_floats); @@ -1843,8 +1833,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { default: UNREACHABLE(); break; } - // If an allocation fails, or SHR hits a hard case, use the runtime system to - // get the correct result. + // If an allocation fails, or SHR or MOD hit a hard case, + // use the runtime system to get the correct result. __ bind(&call_runtime); switch (op_) { @@ -1865,6 +1855,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); break; case Token::MOD: + GenerateRegisterArgsPush(masm); + __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); break; case Token::BIT_OR: __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); @@ -1965,7 +1957,7 @@ void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); __ bind(&after_alloc_failure); - __ fstp(0); // Pop FPU stack before calling runtime. + __ ffree(); __ jmp(&call_runtime); } @@ -2169,8 +2161,8 @@ void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); __ bind(&after_alloc_failure); - __ fstp(0); // Pop FPU stack before calling runtime. - __ jmp(&call_runtime); + __ ffree(); + __ jmp(&call_runtime); } __ bind(¬_floats); break; @@ -5014,9 +5006,11 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { __ j(not_equal, ¬_outermost_js, Label::kNear); __ mov(Operand::StaticVariable(js_entry_sp), ebp); __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); - __ jmp(&invoke, Label::kNear); + Label cont; + __ jmp(&cont, Label::kNear); __ bind(¬_outermost_js); __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); + __ bind(&cont); // Jump to a faked try block that does the invoke, with a faked catch // block that sets the pending exception. @@ -6168,11 +6162,7 @@ void SubStringStub::Generate(MacroAssembler* masm) { __ sub(ecx, edx); __ cmp(ecx, FieldOperand(eax, String::kLengthOffset)); Label not_original_string; - // Shorter than original string's length: an actual substring. - __ j(below, ¬_original_string, Label::kNear); - // Longer than original string's length or negative: unsafe arguments. - __ j(above, &runtime); - // Return original string. + __ j(not_equal, ¬_original_string, Label::kNear); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->sub_string_native(), 1); __ ret(3 * kPointerSize); diff --git a/deps/v8/src/ia32/codegen-ia32.cc b/deps/v8/src/ia32/codegen-ia32.cc index cff6454ff1..ea61910322 100644 --- a/deps/v8/src/ia32/codegen-ia32.cc +++ b/deps/v8/src/ia32/codegen-ia32.cc @@ -397,25 +397,9 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( // Allocate new FixedDoubleArray. // edx: receiver // edi: length of source FixedArray (smi-tagged) - __ lea(esi, Operand(edi, - times_4, - FixedDoubleArray::kHeaderSize + kPointerSize)); + __ lea(esi, Operand(edi, times_4, FixedDoubleArray::kHeaderSize)); __ AllocateInNewSpace(esi, eax, ebx, no_reg, &gc_required, TAG_OBJECT); - Label aligned, aligned_done; - __ test(eax, Immediate(kDoubleAlignmentMask - kHeapObjectTag)); - __ j(zero, &aligned, Label::kNear); - __ mov(FieldOperand(eax, 0), - Immediate(masm->isolate()->factory()->one_pointer_filler_map())); - __ add(eax, Immediate(kPointerSize)); - __ jmp(&aligned_done); - - __ bind(&aligned); - __ mov(Operand(eax, esi, times_1, -kPointerSize-1), - Immediate(masm->isolate()->factory()->one_pointer_filler_map())); - - __ bind(&aligned_done); - // eax: destination FixedDoubleArray // edi: number of elements // edx: receiver diff --git a/deps/v8/src/ia32/debug-ia32.cc b/deps/v8/src/ia32/debug-ia32.cc index 710cbaf19b..d13fa759ca 100644 --- a/deps/v8/src/ia32/debug-ia32.cc +++ b/deps/v8/src/ia32/debug-ia32.cc @@ -172,10 +172,10 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Register state for IC load call (from ic-ia32.cc). // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // ----------------------------------- - Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false); + Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), 0, false); } @@ -194,10 +194,10 @@ void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) { void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // Register state for keyed IC load call (from ic-ia32.cc). // ----------- S t a t e ------------- - // -- ecx : key // -- edx : receiver + // -- eax : key // ----------------------------------- - Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false); + Generate_DebugBreakCallHelper(masm, eax.bit() | edx.bit(), 0, false); } diff --git a/deps/v8/src/ia32/deoptimizer-ia32.cc b/deps/v8/src/ia32/deoptimizer-ia32.cc index 73961e1416..6de2c81b9d 100644 --- a/deps/v8/src/ia32/deoptimizer-ia32.cc +++ b/deps/v8/src/ia32/deoptimizer-ia32.cc @@ -239,13 +239,13 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, // ok: if (FLAG_count_based_interrupts) { - ASSERT_EQ(kJnsInstruction, *(call_target_address - 3)); - ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); + ASSERT_EQ(*(call_target_address - 3), kJnsInstruction); + ASSERT_EQ(*(call_target_address - 2), kJnsOffset); } else { - ASSERT_EQ(kJaeInstruction, *(call_target_address - 3)); - ASSERT_EQ(kJaeOffset, *(call_target_address - 2)); + ASSERT_EQ(*(call_target_address - 3), kJaeInstruction); + ASSERT_EQ(*(call_target_address - 2), kJaeOffset); } - ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); + ASSERT_EQ(*(call_target_address - 1), kCallInstruction); *(call_target_address - 3) = kNopByteOne; *(call_target_address - 2) = kNopByteTwo; Assembler::set_target_address_at(call_target_address, @@ -266,9 +266,9 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code, // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to // restore the conditional branch. - ASSERT_EQ(kNopByteOne, *(call_target_address - 3)); - ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); - ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); + ASSERT_EQ(*(call_target_address - 3), kNopByteOne); + ASSERT_EQ(*(call_target_address - 2), kNopByteTwo); + ASSERT_EQ(*(call_target_address - 1), kCallInstruction); if (FLAG_count_based_interrupts) { *(call_target_address - 3) = kJnsInstruction; *(call_target_address - 2) = kJnsOffset; diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index 266afce204..cf16c5b6ea 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -101,6 +101,13 @@ class JumpPatchSite BASE_EMBEDDED { }; +// TODO(jkummerow): Obsolete as soon as x64 is updated. Remove. +int FullCodeGenerator::self_optimization_header_size() { + UNREACHABLE(); + return 13; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right, with the // return address on top of them. The actual argument count matches the @@ -262,11 +269,11 @@ void FullCodeGenerator::Generate() { // For named function expressions, declare the function name as a // constant. if (scope()->is_function_scope() && scope()->function() != NULL) { - VariableDeclaration* function = scope()->function(); - ASSERT(function->proxy()->var()->mode() == CONST || - function->proxy()->var()->mode() == CONST_HARMONY); - ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); - VisitVariableDeclaration(function); + VariableProxy* proxy = scope()->function(); + ASSERT(proxy->var()->mode() == CONST || + proxy->var()->mode() == CONST_HARMONY); + ASSERT(proxy->var()->location() != Variable::UNALLOCATED); + EmitDeclaration(proxy, proxy->var()->mode(), NULL); } VisitDeclarations(scope()->declarations()); } @@ -756,51 +763,60 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, } -void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { - // The variable in the declaration always resides in the current function - // context. - ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); - if (FLAG_debug_code) { - // Check that we're not inside a with or catch context. - __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); - __ cmp(ebx, isolate()->factory()->with_context_map()); - __ Check(not_equal, "Declaration in with context."); - __ cmp(ebx, isolate()->factory()->catch_context_map()); - __ Check(not_equal, "Declaration in catch context."); - } -} - - -void FullCodeGenerator::VisitVariableDeclaration( - VariableDeclaration* declaration) { +void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function) { // If it was not possible to allocate the variable at compile time, we // need to "declare" it at runtime to make sure it actually exists in the // local context. - VariableProxy* proxy = declaration->proxy(); - VariableMode mode = declaration->mode(); Variable* variable = proxy->var(); - bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; + bool binding_needs_init = (function == NULL) && + (mode == CONST || mode == CONST_HARMONY || mode == LET); switch (variable->location()) { case Variable::UNALLOCATED: - globals_->Add(variable->name()); - globals_->Add(variable->binding_needs_init() - ? isolate()->factory()->the_hole_value() - : isolate()->factory()->undefined_value()); + ++global_count_; break; case Variable::PARAMETER: case Variable::LOCAL: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ mov(StackOperand(variable), result_register()); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ mov(StackOperand(variable), Immediate(isolate()->factory()->the_hole_value())); } break; case Variable::CONTEXT: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); - EmitDebugCheckDeclarationContext(variable); + // The variable in the decl always resides in the current function + // context. + ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); + if (FLAG_debug_code) { + // Check that we're not inside a with or catch context. + __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); + __ cmp(ebx, isolate()->factory()->with_context_map()); + __ Check(not_equal, "Declaration in with context."); + __ cmp(ebx, isolate()->factory()->catch_context_map()); + __ Check(not_equal, "Declaration in catch context."); + } + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ mov(ContextOperand(esi, variable->index()), result_register()); + // We know that we have written a function, which is not a smi. + __ RecordWriteContextSlot(esi, + Context::SlotOffset(variable->index()), + result_register(), + ecx, + kDontSaveFPRegs, + EMIT_REMEMBERED_SET, + OMIT_SMI_CHECK); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ mov(ContextOperand(esi, variable->index()), Immediate(isolate()->factory()->the_hole_value())); // No write barrier since the hole value is in old space. @@ -809,12 +825,14 @@ void FullCodeGenerator::VisitVariableDeclaration( break; case Variable::LOOKUP: { - Comment cmnt(masm_, "[ VariableDeclaration"); + Comment cmnt(masm_, "[ Declaration"); __ push(esi); __ push(Immediate(variable->name())); - // VariableDeclaration nodes are always introduced in one of four modes. - ASSERT(mode == VAR || mode == LET || - mode == CONST || mode == CONST_HARMONY); + // Declaration nodes are always introduced in one of four modes. + ASSERT(mode == VAR || + mode == CONST || + mode == CONST_HARMONY || + mode == LET); PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE; __ push(Immediate(Smi::FromInt(attr))); @@ -822,7 +840,9 @@ void FullCodeGenerator::VisitVariableDeclaration( // Note: For variables we must not push an initial value (such as // 'undefined') because we may have a (legal) redeclaration and we // must not destroy the current value. - if (hole_init) { + if (function != NULL) { + VisitForStackValue(function); + } else if (binding_needs_init) { __ push(Immediate(isolate()->factory()->the_hole_value())); } else { __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. @@ -834,118 +854,6 @@ void FullCodeGenerator::VisitVariableDeclaration( } -void FullCodeGenerator::VisitFunctionDeclaration( - FunctionDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: { - globals_->Add(variable->name()); - Handle<SharedFunctionInfo> function = - Compiler::BuildFunctionInfo(declaration->fun(), script()); - // Check for stack-overflow exception. - if (function.is_null()) return SetStackOverflow(); - globals_->Add(function); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - VisitForAccumulatorValue(declaration->fun()); - __ mov(StackOperand(variable), result_register()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - EmitDebugCheckDeclarationContext(variable); - VisitForAccumulatorValue(declaration->fun()); - __ mov(ContextOperand(esi, variable->index()), result_register()); - // We know that we have written a function, which is not a smi. - __ RecordWriteContextSlot(esi, - Context::SlotOffset(variable->index()), - result_register(), - ecx, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), NO_REGISTERS); - break; - } - - case Variable::LOOKUP: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - __ push(esi); - __ push(Immediate(variable->name())); - __ push(Immediate(Smi::FromInt(NONE))); - VisitForStackValue(declaration->fun()); - __ CallRuntime(Runtime::kDeclareContextSlot, 4); - break; - } - } -} - - -void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - Handle<JSModule> instance = declaration->module()->interface()->Instance(); - ASSERT(!instance.is_null()); - - switch (variable->location()) { - case Variable::UNALLOCATED: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - globals_->Add(variable->name()); - globals_->Add(instance); - Visit(declaration->module()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - EmitDebugCheckDeclarationContext(variable); - __ mov(ContextOperand(esi, variable->index()), Immediate(instance)); - Visit(declaration->module()); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: - // TODO(rossberg) - break; - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ImportDeclaration"); - EmitDebugCheckDeclarationContext(variable); - // TODO(rossberg) - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { - // TODO(rossberg) -} - - void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { // Call the runtime to declare the globals. __ push(esi); // The context is the first argument. @@ -1286,7 +1194,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, // All extension objects were empty and it is safe to use a global // load IC call. - __ mov(edx, GlobalObjectOperand()); + __ mov(eax, GlobalObjectOperand()); __ mov(ecx, var->name()); Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) @@ -1370,7 +1278,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { Comment cmnt(masm_, "Global variable"); // Use inline caching. Variable name is passed in ecx and the global // object in eax. - __ mov(edx, GlobalObjectOperand()); + __ mov(eax, GlobalObjectOperand()); __ mov(ecx, var->name()); Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); @@ -1764,9 +1672,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { break; case NAMED_PROPERTY: if (expr->is_compound()) { - // We need the receiver both on the stack and in edx. - VisitForStackValue(property->obj()); - __ mov(edx, Operand(esp, 0)); + // We need the receiver both on the stack and in the accumulator. + VisitForAccumulatorValue(property->obj()); + __ push(result_register()); } else { VisitForStackValue(property->obj()); } @@ -1774,9 +1682,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case KEYED_PROPERTY: { if (expr->is_compound()) { VisitForStackValue(property->obj()); - VisitForStackValue(property->key()); - __ mov(edx, Operand(esp, kPointerSize)); // Object. - __ mov(ecx, Operand(esp, 0)); // Key. + VisitForAccumulatorValue(property->key()); + __ mov(edx, Operand(esp, 0)); + __ push(eax); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -2019,7 +1927,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); __ mov(ecx, eax); - __ pop(edx); // Receiver. + __ pop(edx); __ pop(eax); // Restore value. Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() @@ -2125,9 +2033,6 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { // Assignment to a property, using a named store IC. - // eax : value - // esp[0] : receiver - Property* prop = expr->target()->AsProperty(); ASSERT(prop != NULL); ASSERT(prop->key()->AsLiteral() != NULL); @@ -2170,9 +2075,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { // Assignment to a property, using a keyed store IC. - // eax : value - // esp[0] : key - // esp[kPointerSize] : receiver // If the assignment starts a block of assignments to the same object, // change to slow case to avoid the quadratic behavior of repeatedly @@ -2185,7 +2087,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { __ pop(result_register()); } - __ pop(ecx); // Key. + __ pop(ecx); if (expr->ends_initialization_block()) { __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. } else { @@ -2218,14 +2120,12 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - __ mov(edx, result_register()); EmitNamedPropertyLoad(expr); context()->Plug(eax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(edx); // Object. - __ mov(ecx, result_register()); // Key. + __ pop(edx); EmitKeyedPropertyLoad(expr); context()->Plug(eax); } @@ -4024,16 +3924,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ push(Immediate(Smi::FromInt(0))); } if (assign_type == NAMED_PROPERTY) { - // Put the object both on the stack and in edx. + // Put the object both on the stack and in the accumulator. VisitForAccumulatorValue(prop->obj()); __ push(eax); - __ mov(edx, eax); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); - VisitForStackValue(prop->key()); - __ mov(edx, Operand(esp, kPointerSize)); // Object. - __ mov(ecx, Operand(esp, 0)); // Key. + VisitForAccumulatorValue(prop->key()); + __ mov(edx, Operand(esp, 0)); + __ push(eax); EmitKeyedPropertyLoad(prop); } } @@ -4180,7 +4079,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "Global variable"); - __ mov(edx, GlobalObjectOperand()); + __ mov(eax, GlobalObjectOperand()); __ mov(ecx, Immediate(proxy->name())); Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); // Use a regular load, not a contextual load, to avoid a reference @@ -4445,8 +4344,7 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) { void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { Scope* declaration_scope = scope()->DeclarationScope(); - if (declaration_scope->is_global_scope() || - declaration_scope->is_module_scope()) { + if (declaration_scope->is_global_scope()) { // Contexts nested in the global context have a canonical empty function // as their closure, not the anonymous closure containing the global // code. Pass a smi sentinel and let the runtime look up the empty diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc index a591af125e..eac2739520 100644 --- a/deps/v8/src/ia32/ic-ia32.cc +++ b/deps/v8/src/ia32/ic-ia32.cc @@ -218,13 +218,13 @@ static void GenerateDictionaryStore(MacroAssembler* masm, void LoadIC::GenerateArrayLength(MacroAssembler* masm) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss); + StubCompiler::GenerateLoadArrayLength(masm, eax, edx, &miss); __ bind(&miss); StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); } @@ -233,13 +233,13 @@ void LoadIC::GenerateArrayLength(MacroAssembler* masm) { void LoadIC::GenerateStringLength(MacroAssembler* masm, bool support_wrappers) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss, + StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss, support_wrappers); __ bind(&miss); StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); @@ -248,13 +248,13 @@ void LoadIC::GenerateStringLength(MacroAssembler* masm, void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss); + StubCompiler::GenerateLoadFunctionPrototype(masm, eax, edx, ebx, &miss); __ bind(&miss); StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); } @@ -443,7 +443,7 @@ static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -451,34 +451,39 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Label probe_dictionary, check_number_dictionary; // Check that the key is a smi. - __ JumpIfNotSmi(ecx, &check_string); + __ JumpIfNotSmi(eax, &check_string); __ bind(&index_smi); // Now the key is known to be a smi. This place is also jumped to from // where a numeric string is converted to a smi. GenerateKeyedLoadReceiverCheck( - masm, edx, eax, Map::kHasIndexedInterceptor, &slow); + masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); // Check the receiver's map to see if it has fast elements. - __ CheckFastElements(eax, &check_number_dictionary); - - GenerateFastArrayLoad(masm, edx, ecx, eax, eax, NULL, &slow); + __ CheckFastElements(ecx, &check_number_dictionary); + + GenerateFastArrayLoad(masm, + edx, + eax, + ecx, + eax, + NULL, + &slow); Isolate* isolate = masm->isolate(); Counters* counters = isolate->counters(); __ IncrementCounter(counters->keyed_load_generic_smi(), 1); __ ret(0); - __ bind(&check_number_dictionary); - __ mov(ebx, ecx); + __ mov(ebx, eax); __ SmiUntag(ebx); - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); + __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); // Check whether the elements is a number dictionary. // edx: receiver // ebx: untagged index - // ecx: key - // eax: elements - __ CheckMap(eax, + // eax: key + // ecx: elements + __ CheckMap(ecx, isolate->factory()->hash_table_map(), &slow, DONT_DO_SMI_CHECK); @@ -486,7 +491,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Push receiver on the stack to free up a register for the dictionary // probing. __ push(edx); - __ LoadFromNumberDictionary(&slow_pop_receiver, eax, ecx, ebx, edx, edi, eax); + __ LoadFromNumberDictionary(&slow_pop_receiver, + ecx, + eax, + ebx, + edx, + edi, + eax); // Pop receiver before returning. __ pop(edx); __ ret(0); @@ -498,15 +509,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ bind(&slow); // Slow case: jump to runtime. // edx: receiver - // ecx: key + // eax: key __ IncrementCounter(counters->keyed_load_generic_slow(), 1); GenerateRuntimeGetProperty(masm); __ bind(&check_string); - GenerateKeyStringCheck(masm, ecx, eax, ebx, &index_string, &slow); + GenerateKeyStringCheck(masm, eax, ecx, ebx, &index_string, &slow); GenerateKeyedLoadReceiverCheck( - masm, edx, eax, Map::kHasNamedInterceptor, &slow); + masm, edx, ecx, Map::kHasNamedInterceptor, &slow); // If the receiver is a fast-case object, check the keyed lookup // cache. Otherwise probe the dictionary. @@ -515,18 +526,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Immediate(isolate->factory()->hash_table_map())); __ j(equal, &probe_dictionary); - // The receiver's map is still in eax, compute the keyed lookup cache hash + // Load the map of the receiver, compute the keyed lookup cache hash // based on 32 bits of the map pointer and the string hash. - if (FLAG_debug_code) { - __ cmp(eax, FieldOperand(edx, HeapObject::kMapOffset)); - __ Check(equal, "Map is no longer in eax."); - } - __ mov(ebx, eax); // Keep the map around for later. - __ shr(eax, KeyedLookupCache::kMapHashShift); - __ mov(edi, FieldOperand(ecx, String::kHashFieldOffset)); + __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); + __ mov(ecx, ebx); + __ shr(ecx, KeyedLookupCache::kMapHashShift); + __ mov(edi, FieldOperand(eax, String::kHashFieldOffset)); __ shr(edi, String::kHashShift); - __ xor_(eax, edi); - __ and_(eax, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); + __ xor_(ecx, edi); + __ and_(ecx, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); // Load the key (consisting of map and symbol) from the cache and // check for match. @@ -538,7 +546,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { for (int i = 0; i < kEntriesPerBucket - 1; i++) { Label try_next_entry; - __ mov(edi, eax); + __ mov(edi, ecx); __ shl(edi, kPointerSizeLog2 + 1); if (i != 0) { __ add(edi, Immediate(kPointerSize * i * 2)); @@ -546,25 +554,25 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &try_next_entry); __ add(edi, Immediate(kPointerSize)); - __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys)); + __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys)); __ j(equal, &hit_on_nth_entry[i]); __ bind(&try_next_entry); } - __ lea(edi, Operand(eax, 1)); + __ lea(edi, Operand(ecx, 1)); __ shl(edi, kPointerSizeLog2 + 1); __ add(edi, Immediate(kPointerSize * (kEntriesPerBucket - 1) * 2)); __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &slow); __ add(edi, Immediate(kPointerSize)); - __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys)); + __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &slow); // Get field offset. // edx : receiver // ebx : receiver's map - // ecx : key - // eax : lookup cache index + // eax : key + // ecx : lookup cache index ExternalReference cache_field_offsets = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); @@ -572,12 +580,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { for (int i = kEntriesPerBucket - 1; i >= 0; i--) { __ bind(&hit_on_nth_entry[i]); if (i != 0) { - __ add(eax, Immediate(i)); + __ add(ecx, Immediate(i)); } __ mov(edi, - Operand::StaticArray(eax, times_pointer_size, cache_field_offsets)); - __ movzx_b(eax, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); - __ sub(edi, eax); + Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets)); + __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); + __ sub(edi, ecx); __ j(above_equal, &property_array_property); if (i != 0) { __ jmp(&load_in_object_property); @@ -586,9 +594,9 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Load in-object property. __ bind(&load_in_object_property); - __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceSizeOffset)); - __ add(eax, edi); - __ mov(eax, FieldOperand(edx, eax, times_pointer_size, 0)); + __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset)); + __ add(ecx, edi); + __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0)); __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); __ ret(0); @@ -604,16 +612,16 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // exists. __ bind(&probe_dictionary); - __ mov(eax, FieldOperand(edx, JSObject::kMapOffset)); - __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); - GenerateGlobalInstanceTypeCheck(masm, eax, &slow); + __ mov(ecx, FieldOperand(edx, JSObject::kMapOffset)); + __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); + GenerateGlobalInstanceTypeCheck(masm, ecx, &slow); - GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax); + GenerateDictionaryLoad(masm, &slow, ebx, eax, ecx, edi, eax); __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); __ ret(0); __ bind(&index_string); - __ IndexFromHash(ebx, ecx); + __ IndexFromHash(ebx, eax); // Now jump to the place where smi keys are handled. __ jmp(&index_smi); } @@ -621,15 +629,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key (index) + // -- eax : key (index) // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; Register receiver = edx; - Register index = ecx; - Register scratch = ebx; + Register index = eax; + Register scratch = ecx; Register result = eax; StringCharAtGenerator char_at_generator(receiver, @@ -653,7 +661,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -663,24 +671,24 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { __ JumpIfSmi(edx, &slow); // Check that the key is an array index, that is Uint32. - __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask)); + __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); __ j(not_zero, &slow); // Get the map of the receiver. - __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); + __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset)); - __ and_(eax, Immediate(kSlowCaseBitFieldMask)); - __ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor)); + __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset)); + __ and_(ecx, Immediate(kSlowCaseBitFieldMask)); + __ cmp(ecx, Immediate(1 << Map::kHasIndexedInterceptor)); __ j(not_zero, &slow); // Everything is fine, call runtime. - __ pop(eax); + __ pop(ecx); __ push(edx); // receiver - __ push(ecx); // key - __ push(eax); // return address + __ push(eax); // key + __ push(ecx); // return address // Perform tail call to the entry. ExternalReference ref = @@ -695,20 +703,20 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label slow, notin; Factory* factory = masm->isolate()->factory(); Operand mapped_location = - GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); + GenerateMappedArgumentsLookup(masm, edx, eax, ebx, ecx, ¬in, &slow); __ mov(eax, mapped_location); __ Ret(); __ bind(¬in); // The unmapped lookup expects that the parameter map is in ebx. Operand unmapped_location = - GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); + GenerateUnmappedArgumentsLookup(masm, eax, ebx, ecx, &slow); __ cmp(unmapped_location, factory->the_hole_value()); __ j(equal, &slow); __ mov(eax, unmapped_location); @@ -1300,15 +1308,15 @@ void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- // Probe the stub cache. Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC); - Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, - eax); + Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx, + edx); // Cache miss: Jump to runtime. GenerateMiss(masm); @@ -1317,17 +1325,17 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { void LoadIC::GenerateNormal(MacroAssembler* masm) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); + GenerateStringDictionaryReceiverCheck(masm, eax, edx, ebx, &miss); - // eax: elements + // edx: elements // Search the dictionary placing the result in eax. - GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, eax); + GenerateDictionaryLoad(masm, &miss, edx, ecx, edi, ebx, eax); __ ret(0); // Cache miss: Jump to runtime. @@ -1338,15 +1346,15 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); __ pop(ebx); - __ push(edx); // receiver + __ push(eax); // receiver __ push(ecx); // name __ push(ebx); // return address @@ -1359,7 +1367,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -1368,7 +1376,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) { __ pop(ebx); __ push(edx); // receiver - __ push(ecx); // name + __ push(eax); // name __ push(ebx); // return address // Perform tail call to the entry. @@ -1382,14 +1390,14 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- __ pop(ebx); __ push(edx); // receiver - __ push(ecx); // name + __ push(eax); // name __ push(ebx); // return address // Perform tail call to the entry. diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc index d416662a1e..8fb4c79196 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc @@ -2059,9 +2059,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RelocInfo::CODE_TARGET, instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - // Get the deoptimization index of the LLazyBailout-environment that - // corresponds to this instruction. - LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Put the result value into the eax slot and restore all registers. @@ -2115,7 +2114,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->global_object()).is(edx)); + ASSERT(ToRegister(instr->global_object()).is(eax)); ASSERT(ToRegister(instr->result()).is(eax)); __ mov(ecx, instr->name()); @@ -2313,7 +2312,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->object()).is(edx)); + ASSERT(ToRegister(instr->object()).is(eax)); ASSERT(ToRegister(instr->result()).is(eax)); __ mov(ecx, instr->name()); @@ -2534,7 +2533,7 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); ASSERT(ToRegister(instr->object()).is(edx)); - ASSERT(ToRegister(instr->key()).is(ecx)); + ASSERT(ToRegister(instr->key()).is(eax)); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2544,29 +2543,25 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register result = ToRegister(instr->result()); - if (instr->hydrogen()->from_inlined()) { - __ lea(result, Operand(esp, -2 * kPointerSize)); - } else { - // Check for arguments adapter frame. - Label done, adapted; - __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); - __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); - __ cmp(Operand(result), - Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); - __ j(equal, &adapted, Label::kNear); - - // No arguments adaptor frame. - __ mov(result, Operand(ebp)); - __ jmp(&done, Label::kNear); + // Check for arguments adapter frame. + Label done, adapted; + __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); + __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); + __ cmp(Operand(result), + Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + __ j(equal, &adapted, Label::kNear); - // Arguments adaptor frame present. - __ bind(&adapted); - __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); + // No arguments adaptor frame. + __ mov(result, Operand(ebp)); + __ jmp(&done, Label::kNear); - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ bind(&done); - } + // Arguments adaptor frame present. + __ bind(&adapted); + __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); + + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ bind(&done); } @@ -2671,7 +2666,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // Invoke the function. __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -2688,11 +2683,6 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } -void LCodeGen::DoDrop(LDrop* instr) { - __ Drop(instr->count()); -} - - void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); @@ -2739,8 +2729,7 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - EDIState edi_state) { + CallKind call_kind) { bool can_invoke_directly = !function->NeedsArgumentsAdaption() || function->shared()->formal_parameter_count() == arity; @@ -2748,9 +2737,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, RecordPosition(pointers->position()); if (can_invoke_directly) { - if (edi_state == EDI_UNINITIALIZED) { - __ LoadHeapObject(edi, function); - } + __ LoadHeapObject(edi, function); // Change context if needed. bool change_context = @@ -2793,8 +2780,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { CallKnownFunction(instr->function(), instr->arity(), instr, - CALL_AS_METHOD, - EDI_UNINITIALIZED); + CALL_AS_METHOD); } @@ -3240,21 +3226,13 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->context()).is(esi)); ASSERT(ToRegister(instr->function()).is(edi)); ASSERT(instr->HasPointerMap()); - - if (instr->known_function().is_null()) { - LPointerMap* pointers = instr->pointer_map(); - RecordPosition(pointers->position()); - SafepointGenerator generator( - this, pointers, Safepoint::kLazyDeopt); - ParameterCount count(instr->arity()); - __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); - } else { - CallKnownFunction(instr->known_function(), - instr->arity(), - instr, - CALL_AS_METHOD, - EDI_CONTAINS_TARGET); - } + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + RecordPosition(pointers->position()); + SafepointGenerator generator( + this, pointers, Safepoint::kLazyDeopt); + ParameterCount count(instr->arity()); + __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); } @@ -3309,11 +3287,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(eax)); - CallKnownFunction(instr->target(), - instr->arity(), - instr, - CALL_AS_FUNCTION, - EDI_UNINITIALIZED); + CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); } @@ -3486,18 +3460,15 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { void LCodeGen::DoStoreKeyedFastDoubleElement( LStoreKeyedFastDoubleElement* instr) { XMMRegister value = ToDoubleRegister(instr->value()); + Label have_value; - if (instr->NeedsCanonicalization()) { - Label have_value; - - __ ucomisd(value, value); - __ j(parity_odd, &have_value); // NaN. + __ ucomisd(value, value); + __ j(parity_odd, &have_value); // NaN. - ExternalReference canonical_nan_reference = - ExternalReference::address_of_canonical_non_hole_nan(); - __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); - __ bind(&have_value); - } + ExternalReference canonical_nan_reference = + ExternalReference::address_of_canonical_non_hole_nan(); + __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); + __ bind(&have_value); Operand double_store_operand = BuildFastArrayOperand( instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, @@ -4210,21 +4181,12 @@ void LCodeGen::DoCheckMapCommon(Register reg, } -void LCodeGen::DoCheckMaps(LCheckMaps* instr) { +void LCodeGen::DoCheckMap(LCheckMap* instr) { LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); - - Label success; - SmallMapList* map_set = instr->hydrogen()->map_set(); - for (int i = 0; i < map_set->length() - 1; i++) { - Handle<Map> map = map_set->at(i); - __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); - __ j(equal, &success); - } - Handle<Map> map = map_set->last(); - DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment()); - __ bind(&success); + Handle<Map> map = instr->hydrogen()->map(); + DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment()); } @@ -4335,14 +4297,6 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { deferred->entry(), TAG_OBJECT); - __ bind(deferred->exit()); - if (FLAG_debug_code) { - Label is_in_new_space; - __ JumpIfInNewSpace(result, scratch, &is_in_new_space); - __ Abort("Allocated object is not in new-space"); - __ bind(&is_in_new_space); - } - // Load the initial map. Register map = scratch; __ LoadHeapObject(scratch, constructor); @@ -4377,14 +4331,14 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { __ mov(FieldOperand(result, property_offset), scratch); } } + + __ bind(deferred->exit()); } void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); - int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the // result register contain a valid pointer because it is already @@ -4392,9 +4346,8 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { __ Set(result, Immediate(0)); PushSafepointRegistersScope scope(this); - __ push(Immediate(Smi::FromInt(instance_size))); - CallRuntimeFromDeferred( - Runtime::kAllocateInNewSpace, 1, instr, instr->context()); + __ PushHeapObject(constructor); + CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr, instr->context()); __ StoreToSafepointRegisterSlot(result, eax); } @@ -4462,13 +4415,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ LoadHeapObject(ecx, object); __ cmp(source, ecx); __ Assert(equal, "Unexpected object literal boilerplate"); - __ mov(ecx, FieldOperand(source, HeapObject::kMapOffset)); - __ cmp(ecx, Handle<Map>(object->map())); - __ Assert(equal, "Unexpected boilerplate map"); - __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); - __ and_(ecx, Map::kElementsKindMask); - __ cmp(ecx, object->GetElementsKind() << Map::kElementsKindShift); - __ Assert(equal, "Unexpected boilerplate elements kind"); } // Only elements backing stores for non-COW arrays need to be copied. @@ -4538,10 +4484,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ mov(FieldOperand(result, total_offset + 4), Immediate(value_high)); } } else if (elements->IsFixedArray()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); for (int i = 0; i < elements_length; i++) { int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(object, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); __ lea(ecx, Operand(result, *offset)); @@ -4565,23 +4510,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, void LCodeGen::DoFastLiteral(LFastLiteral* instr) { ASSERT(ToRegister(instr->context()).is(esi)); int size = instr->hydrogen()->total_size(); - ElementsKind boilerplate_elements_kind = - instr->hydrogen()->boilerplate()->GetElementsKind(); - - // Deopt if the literal boilerplate ElementsKind is of a type different than - // the expected one. The check isn't necessary if the boilerplate has already - // been converted to FAST_ELEMENTS. - if (boilerplate_elements_kind != FAST_ELEMENTS) { - __ LoadHeapObject(ebx, instr->hydrogen()->boilerplate()); - __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); - // Load the map's "bit field 2". We only need the first byte, - // but the following masking takes care of that anyway. - __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); - // Retrieve elements_kind from bit field 2. - __ and_(ecx, Map::kElementsKindMask); - __ cmp(ecx, boilerplate_elements_kind << Map::kElementsKindShift); - DeoptimizeIf(not_equal, instr->environment()); - } // Allocate all objects that are part of the literal in one big // allocation. This avoids multiple limit checks. @@ -4866,7 +4794,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { LOperand* key = instr->key(); __ push(ToOperand(obj)); EmitPushTaggedOperand(key); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); // Create safepoint generator that will also ensure enough space in the @@ -4964,7 +4892,7 @@ void LCodeGen::DoIn(LIn* instr) { LOperand* key = instr->key(); EmitPushTaggedOperand(key); EmitPushTaggedOperand(obj); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h index a2810f05c3..52befc6974 100644 --- a/deps/v8/src/ia32/lithium-codegen-ia32.h +++ b/deps/v8/src/ia32/lithium-codegen-ia32.h @@ -206,18 +206,12 @@ class LCodeGen BASE_EMBEDDED { LInstruction* instr, LOperand* context); - enum EDIState { - EDI_UNINITIALIZED, - EDI_CONTAINS_TARGET - }; - // Generate a direct call to a known function. Expects the function // to be in edi. void CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - EDIState edi_state); + CallKind call_kind); void RecordSafepointWithLazyDeopt(LInstruction* instr, SafepointMode safepoint_mode); diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc index 5adaf431bd..186b346c70 100644 --- a/deps/v8/src/ia32/lithium-ia32.cc +++ b/deps/v8/src/ia32/lithium-ia32.cc @@ -729,6 +729,22 @@ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { } +LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id) { + ASSERT(instruction_pending_deoptimization_environment_ == NULL); + ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); + instruction_pending_deoptimization_environment_ = instr; + pending_deoptimization_ast_id_ = ast_id; + return instr; +} + + +void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { + instruction_pending_deoptimization_environment_ = NULL; + pending_deoptimization_ast_id_ = AstNode::kNoNumber; +} + + LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize) { @@ -741,10 +757,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, if (hinstr->HasObservableSideEffects()) { ASSERT(hinstr->next()->IsSimulate()); HSimulate* sim = HSimulate::cast(hinstr->next()); - ASSERT(instruction_pending_deoptimization_environment_ == NULL); - ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); - instruction_pending_deoptimization_environment_ = instr; - pending_deoptimization_ast_id_ = sim->ast_id(); + instr = SetInstructionPendingDeoptimizationEnvironment( + instr, sim->ast_id()); } // If instruction does not have side-effects lazy deoptimization @@ -762,6 +776,12 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, } +LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { + instr->MarkAsSaveDoubles(); + return instr; +} + + LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { ASSERT(!instr->HasPointerMap()); instr->set_pointer_map(new(zone()) LPointerMap(position_)); @@ -1310,7 +1330,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; LOperand* input = UseRegisterAtStart(instr->value()); LBitNotI* result = new(zone()) LBitNotI(input); return DefineSameAsFirst(result); @@ -1335,12 +1354,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { } -LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { - UNIMPLEMENTED(); - return NULL; -} - - LInstruction* LChunkBuilder::DoMod(HMod* instr) { if (instr->representation().IsInteger32()) { ASSERT(instr->left()->representation().IsInteger32()); @@ -1787,9 +1800,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { } -LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { +LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - LCheckMaps* result = new(zone()) LCheckMaps(value); + LCheckMap* result = new(zone()) LCheckMap(value); return AssignEnvironment(result); } @@ -1849,7 +1862,7 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* global_object = UseFixed(instr->global_object(), edx); + LOperand* global_object = UseFixed(instr->global_object(), eax); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, eax), instr); @@ -1909,7 +1922,7 @@ LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( ASSERT(instr->representation().IsTagged()); if (instr->need_generic()) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* obj = UseFixed(instr->object(), edx); + LOperand* obj = UseFixed(instr->object(), eax); LLoadNamedFieldPolymorphic* result = new(zone()) LLoadNamedFieldPolymorphic(context, obj); return MarkAsCall(DefineFixed(result, eax), instr); @@ -1925,7 +1938,7 @@ LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* object = UseFixed(instr->object(), edx); + LOperand* object = UseFixed(instr->object(), eax); LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -2004,7 +2017,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); LOperand* object = UseFixed(instr->object(), edx); - LOperand* key = UseFixed(instr->key(), ecx); + LOperand* key = UseFixed(instr->key(), eax); LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(context, object, key); @@ -2335,12 +2348,9 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { ASSERT(pending_deoptimization_ast_id_ == instr->ast_id()); LLazyBailout* lazy_bailout = new(zone()) LLazyBailout; LInstruction* result = AssignEnvironment(lazy_bailout); - // Store the lazy deopt environment with the instruction if needed. Right - // now it is only used for LInstanceOfKnownGlobal. instruction_pending_deoptimization_environment_-> - SetDeferredLazyDeoptimizationEnvironment(result->environment()); - instruction_pending_deoptimization_environment_ = NULL; - pending_deoptimization_ast_id_ = AstNode::kNoNumber; + set_deoptimization_environment(result->environment()); + ClearInstructionPendingDeoptimizationEnvironment(); return result; } @@ -2370,8 +2380,8 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { undefined, instr->call_kind(), instr->is_construct()); - if (instr->arguments_var() != NULL) { - inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject()); + if (instr->arguments() != NULL) { + inner->Bind(instr->arguments(), graph()->GetArgumentsObject()); } current_block_->UpdateEnvironment(inner); chunk_->AddInlinedClosure(instr->closure()); @@ -2380,20 +2390,10 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { - LInstruction* pop = NULL; - - HEnvironment* env = current_block_->last_environment(); - - if (instr->arguments_pushed()) { - int argument_count = env->arguments_environment()->parameter_count(); - pop = new(zone()) LDrop(argument_count); - argument_count_ -= argument_count; - } - HEnvironment* outer = current_block_->last_environment()-> DiscardInlined(false); current_block_->UpdateEnvironment(outer); - return pop; + return NULL; } diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h index 09f0b0d729..4ecce96d0f 100644 --- a/deps/v8/src/ia32/lithium-ia32.h +++ b/deps/v8/src/ia32/lithium-ia32.h @@ -65,7 +65,7 @@ class LCodeGen; V(CallStub) \ V(CheckFunction) \ V(CheckInstanceType) \ - V(CheckMaps) \ + V(CheckMap) \ V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ @@ -174,8 +174,7 @@ class LCodeGen; V(CheckMapValue) \ V(LoadFieldByIndex) \ V(DateField) \ - V(WrapReceiver) \ - V(Drop) + V(WrapReceiver) #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ @@ -199,7 +198,8 @@ class LInstruction: public ZoneObject { LInstruction() : environment_(NULL), hydrogen_value_(NULL), - is_call_(false) { } + is_call_(false), + is_save_doubles_(false) { } virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; @@ -242,12 +242,22 @@ class LInstruction: public ZoneObject { void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } + void set_deoptimization_environment(LEnvironment* env) { + deoptimization_environment_.set(env); + } + LEnvironment* deoptimization_environment() const { + return deoptimization_environment_.get(); + } + bool HasDeoptimizationEnvironment() const { + return deoptimization_environment_.is_set(); + } void MarkAsCall() { is_call_ = true; } + void MarkAsSaveDoubles() { is_save_doubles_ = true; } // Interface to the register allocator and iterators. bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; } virtual bool HasResult() const = 0; virtual LOperand* result() = 0; @@ -268,7 +278,9 @@ class LInstruction: public ZoneObject { LEnvironment* environment_; SetOncePointer<LPointerMap> pointer_map_; HValue* hydrogen_value_; + SetOncePointer<LEnvironment> deoptimization_environment_; bool is_call_; + bool is_save_doubles_; }; @@ -513,8 +525,9 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { public: + LArgumentsElements() { } + DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") - DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) }; @@ -831,15 +844,6 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 2, 1> { DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) Handle<JSFunction> function() const { return hydrogen()->function(); } - LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { - return lazy_deopt_env_; - } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { - lazy_deopt_env_ = env; - } - - private: - LEnvironment* lazy_deopt_env_; }; @@ -1397,19 +1401,6 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; -class LDrop: public LTemplateInstruction<0, 0, 0> { - public: - explicit LDrop(int count) : count_(count) { } - - int count() const { return count_; } - - DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") - - private: - int count_; -}; - - class LThisFunction: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") @@ -1498,7 +1489,6 @@ class LInvokeFunction: public LTemplateInstruction<1, 2, 0> { virtual void PrintDataTo(StringStream* stream); int arity() const { return hydrogen()->argument_count() - 1; } - Handle<JSFunction> known_function() { return hydrogen()->known_function(); } }; @@ -1797,8 +1787,6 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - - bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; @@ -1961,14 +1949,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> { }; -class LCheckMaps: public LTemplateInstruction<0, 1, 0> { +class LCheckMap: public LTemplateInstruction<0, 1, 0> { public: - explicit LCheckMaps(LOperand* value) { + explicit LCheckMap(LOperand* value) { inputs_[0] = value; } - DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") - DECLARE_HYDROGEN_ACCESSOR(CheckMaps) + DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") + DECLARE_HYDROGEN_ACCESSOR(CheckMap) }; @@ -2483,6 +2471,11 @@ class LChunkBuilder BASE_EMBEDDED { LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); + LInstruction* MarkAsSaveDoubles(LInstruction* instr); + + LInstruction* SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id); + void ClearInstructionPendingDeoptimizationEnvironment(); LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, int* argument_index_accumulator); diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc index 0029f33b1a..04d6b62c80 100644 --- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc +++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc @@ -501,13 +501,9 @@ void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_equal) { - if (c == 0) { - __ test(current_character(), Immediate(mask)); - } else { - __ mov(eax, mask); - __ and_(eax, current_character()); - __ cmp(eax, c); - } + __ mov(eax, current_character()); + __ and_(eax, mask); + __ cmp(eax, c); BranchOrBacktrack(equal, on_equal); } @@ -515,13 +511,9 @@ void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_not_equal) { - if (c == 0) { - __ test(current_character(), Immediate(mask)); - } else { - __ mov(eax, mask); - __ and_(eax, current_character()); - __ cmp(eax, c); - } + __ mov(eax, current_character()); + __ and_(eax, mask); + __ cmp(eax, c); BranchOrBacktrack(not_equal, on_not_equal); } @@ -533,51 +525,12 @@ void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( Label* on_not_equal) { ASSERT(minus < String::kMaxUtf16CodeUnit); __ lea(eax, Operand(current_character(), -minus)); - if (c == 0) { - __ test(eax, Immediate(mask)); - } else { - __ and_(eax, mask); - __ cmp(eax, c); - } + __ and_(eax, mask); + __ cmp(eax, c); BranchOrBacktrack(not_equal, on_not_equal); } -void RegExpMacroAssemblerIA32::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - __ lea(eax, Operand(current_character(), -from)); - __ cmp(eax, to - from); - BranchOrBacktrack(below_equal, on_in_range); -} - - -void RegExpMacroAssemblerIA32::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - __ lea(eax, Operand(current_character(), -from)); - __ cmp(eax, to - from); - BranchOrBacktrack(above, on_not_in_range); -} - - -void RegExpMacroAssemblerIA32::CheckBitInTable( - Handle<ByteArray> table, - Label* on_bit_set) { - __ mov(eax, Immediate(table)); - Register index = current_character(); - if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { - __ mov(ebx, kTableSize - 1); - __ and_(ebx, current_character()); - index = ebx; - } - __ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0); - BranchOrBacktrack(not_equal, on_bit_set); -} - - bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { // Range checks (c in min..max) are generally implemented by an unsigned diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h index 78cd06958c..d504470280 100644 --- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h +++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h @@ -78,14 +78,6 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler { uc16 minus, uc16 mask, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); - // Checks whether the given offset from the current position is before // the end of the string. virtual void CheckPosition(int cp_offset, Label* on_outside_input); diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index e148e2f525..eb86b2f523 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -406,7 +406,6 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(receiver); __ push(holder); __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); - __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); } @@ -420,12 +419,12 @@ static void CompileCallLoadPropertyWithInterceptor( __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()), - 6); + 5); } // Number of pointers to be reserved on stack for fast API call. -static const int kFastApiCallArguments = 4; +static const int kFastApiCallArguments = 3; // Reserves space for the extra arguments to API function in the @@ -473,11 +472,10 @@ static void GenerateFastApiCall(MacroAssembler* masm, // -- esp[8] : api function // (first fast api call extra argument) // -- esp[12] : api call data - // -- esp[16] : isolate - // -- esp[20] : last argument + // -- esp[16] : last argument // -- ... - // -- esp[(argc + 4) * 4] : first argument - // -- esp[(argc + 5) * 4] : receiver + // -- esp[(argc + 3) * 4] : first argument + // -- esp[(argc + 4) * 4] : receiver // ----------------------------------- // Get the function and setup the context. Handle<JSFunction> function = optimization.constant_function(); @@ -495,11 +493,9 @@ static void GenerateFastApiCall(MacroAssembler* masm, } else { __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); } - __ mov(Operand(esp, 4 * kPointerSize), - Immediate(reinterpret_cast<int>(masm->isolate()))); // Prepare arguments. - __ lea(eax, Operand(esp, 4 * kPointerSize)); + __ lea(eax, Operand(esp, 3 * kPointerSize)); const int kApiArgc = 1; // API function gets reference to the v8::Arguments. @@ -683,7 +679,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 6); + 5); // Restore the name_ register. __ pop(name_); @@ -1038,7 +1034,6 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, } else { __ push(Immediate(Handle<Object>(callback->data()))); } - __ push(Immediate(reinterpret_cast<int>(isolate()))); // Save a pointer to where we pushed the arguments pointer. // This will be passed as the const AccessorInfo& to the C++ callback. @@ -1049,9 +1044,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, __ push(scratch3); // Restore return address. - // 4 elements array for v8::Arguments::values_, handler for name and pointer + // 3 elements array for v8::Arguments::values_, handler for name and pointer // to the values (it considered as smi in GC). - const int kStackSpace = 6; + const int kStackSpace = 5; const int kApiArgc = 2; __ PrepareCallApiFunction(kApiArgc); @@ -1218,7 +1213,6 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, __ push(holder_reg); __ mov(holder_reg, Immediate(callback)); __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); - __ push(Immediate(reinterpret_cast<int>(isolate()))); __ push(holder_reg); __ push(name_reg); __ push(scratch2); // restore return address @@ -1226,7 +1220,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), masm()->isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1242,7 +1236,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } @@ -2180,7 +2174,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( name, depth, &miss); // Move the return address on top of the stack. - __ mov(eax, Operand(esp, 4 * kPointerSize)); + __ mov(eax, Operand(esp, 3 * kPointerSize)); __ mov(Operand(esp, 0 * kPointerSize), eax); // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains @@ -2709,27 +2703,27 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, Handle<JSObject> object, Handle<JSObject> last) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; // Check that the receiver isn't a smi. - __ JumpIfSmi(edx, &miss); + __ JumpIfSmi(eax, &miss); ASSERT(last->IsGlobalObject() || last->HasFastProperties()); // Check the maps of the full prototype chain. Also check that // global property cells up to (but not including) the last object // in the prototype chain are empty. - CheckPrototypes(object, edx, last, ebx, eax, edi, name, &miss); + CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); // If the last object in the prototype chain is a global object, // check that the global property cell is empty. if (last->IsGlobalObject()) { GenerateCheckPropertyCell( - masm(), Handle<GlobalObject>::cast(last), name, eax, &miss); + masm(), Handle<GlobalObject>::cast(last), name, edx, &miss); } // Return undefined if maps of the full prototype chain are still the @@ -2750,13 +2744,13 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, int index, Handle<String> name) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - GenerateLoadField(object, holder, edx, ebx, eax, edi, index, name, &miss); + GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); @@ -2771,13 +2765,13 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback( Handle<JSObject> holder, Handle<AccessorInfo> callback) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, callback, + GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, callback, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); @@ -2792,13 +2786,13 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, Handle<JSFunction> value, Handle<String> name) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; - GenerateLoadConstant(object, holder, edx, ebx, eax, edi, value, name, &miss); + GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); @@ -2811,8 +2805,8 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver, Handle<JSObject> holder, Handle<String> name) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; @@ -2822,7 +2816,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver, // TODO(368): Compile in the whole chain: all the interceptors in // prototypes and ultimate answer. - GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi, + GenerateLoadInterceptor(receiver, holder, &lookup, eax, ecx, edx, ebx, edi, name, &miss); __ bind(&miss); @@ -2840,15 +2834,15 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal( Handle<String> name, bool is_dont_delete) { // ----------- S t a t e ------------- + // -- eax : receiver // -- ecx : name - // -- edx : receiver // -- esp[0] : return address // ----------------------------------- Label miss; // Check that the maps haven't changed. - __ JumpIfSmi(edx, &miss); - CheckPrototypes(object, edx, holder, ebx, eax, edi, name, &miss); + __ JumpIfSmi(eax, &miss); + CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); // Get the value from the cell. if (Serializer::enabled()) { @@ -2886,7 +2880,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, Handle<JSObject> holder, int index) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -2896,10 +2890,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, __ IncrementCounter(counters->keyed_load_field(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); - GenerateLoadField(receiver, holder, edx, ebx, eax, edi, index, name, &miss); + GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); __ bind(&miss); __ DecrementCounter(counters->keyed_load_field(), 1); @@ -2916,7 +2910,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( Handle<JSObject> holder, Handle<AccessorInfo> callback) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -2926,10 +2920,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( __ IncrementCounter(counters->keyed_load_callback(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); - GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, callback, + GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, edi, callback, name, &miss); __ bind(&miss); @@ -2947,7 +2941,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( Handle<JSObject> holder, Handle<JSFunction> value) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -2957,11 +2951,11 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( __ IncrementCounter(counters->keyed_load_constant_function(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); GenerateLoadConstant( - receiver, holder, edx, ebx, eax, edi, value, name, &miss); + receiver, holder, edx, ebx, ecx, edi, value, name, &miss); __ bind(&miss); __ DecrementCounter(counters->keyed_load_constant_function(), 1); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); @@ -2976,7 +2970,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( Handle<JSObject> holder, Handle<String> name) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -2986,12 +2980,12 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( __ IncrementCounter(counters->keyed_load_interceptor(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); LookupResult lookup(isolate()); LookupPostInterceptor(holder, name, &lookup); - GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi, + GenerateLoadInterceptor(receiver, holder, &lookup, edx, eax, ecx, ebx, edi, name, &miss); __ bind(&miss); __ DecrementCounter(counters->keyed_load_interceptor(), 1); @@ -3005,7 +2999,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( Handle<String> name) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3015,10 +3009,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( __ IncrementCounter(counters->keyed_load_array_length(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); - GenerateLoadArrayLength(masm(), edx, eax, &miss); + GenerateLoadArrayLength(masm(), edx, ecx, &miss); __ bind(&miss); __ DecrementCounter(counters->keyed_load_array_length(), 1); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); @@ -3031,7 +3025,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( Handle<String> name) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3041,10 +3035,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( __ IncrementCounter(counters->keyed_load_string_length(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); - GenerateLoadStringLength(masm(), edx, eax, ebx, &miss, true); + GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); __ bind(&miss); __ DecrementCounter(counters->keyed_load_string_length(), 1); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); @@ -3057,7 +3051,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( Handle<String> name) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3067,10 +3061,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( __ IncrementCounter(counters->keyed_load_function_prototype(), 1); // Check that the name has not changed. - __ cmp(ecx, Immediate(name)); + __ cmp(eax, Immediate(name)); __ j(not_equal, &miss); - GenerateLoadFunctionPrototype(masm(), edx, eax, ebx, &miss); + GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); __ bind(&miss); __ DecrementCounter(counters->keyed_load_function_prototype(), 1); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); @@ -3083,7 +3077,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( Handle<Map> receiver_map) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3104,7 +3098,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( MapHandleList* receiver_maps, CodeHandleList* handler_ics) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3268,7 +3262,7 @@ Handle<Code> ConstructStubCompiler::CompileConstructStub( void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3276,15 +3270,21 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - __ JumpIfNotSmi(ecx, &miss_force_generic); - __ mov(ebx, ecx); + __ JumpIfNotSmi(eax, &miss_force_generic); + __ mov(ebx, eax); __ SmiUntag(ebx); - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); + __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); // Push receiver on the stack to free up a register for the dictionary // probing. __ push(edx); - __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax); + __ LoadFromNumberDictionary(&slow, + ecx, + eax, + ebx, + edx, + edi, + eax); // Pop receiver before returning. __ pop(edx); __ ret(0); @@ -3293,6 +3293,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( __ pop(edx); // ----------- S t a t e ------------- + // -- eax : value // -- ecx : key // -- edx : receiver // -- esp[0] : return address @@ -3304,6 +3305,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( __ bind(&miss_force_generic); // ----------- S t a t e ------------- + // -- eax : value // -- ecx : key // -- edx : receiver // -- esp[0] : return address @@ -3315,44 +3317,11 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( } -static void GenerateSmiKeyCheck(MacroAssembler* masm, - Register key, - Register scratch, - XMMRegister xmm_scratch0, - XMMRegister xmm_scratch1, - Label* fail) { - // Check that key is a smi and if SSE2 is available a heap number - // containing a smi and branch if the check fails. - if (CpuFeatures::IsSupported(SSE2)) { - CpuFeatures::Scope use_sse2(SSE2); - Label key_ok; - __ JumpIfSmi(key, &key_ok); - __ cmp(FieldOperand(key, HeapObject::kMapOffset), - Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map()))); - __ j(not_equal, fail); - __ movdbl(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset)); - __ cvttsd2si(scratch, Operand(xmm_scratch0)); - __ cvtsi2sd(xmm_scratch1, scratch); - __ ucomisd(xmm_scratch1, xmm_scratch0); - __ j(not_equal, fail); - __ j(parity_even, fail); // NaN. - // Check if the key fits in the smi range. - __ cmp(scratch, 0xc0000000); - __ j(sign, fail); - __ SmiTag(scratch); - __ mov(key, scratch); - __ bind(&key_ok); - } else { - __ JumpIfNotSmi(key, fail); - } -} - - void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, ElementsKind elements_kind) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3361,41 +3330,41 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(eax, &miss_force_generic); // Check that the index is in range. __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); - __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); + __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset)); // Unsigned comparison catches both negative and too-large values. __ j(above_equal, &miss_force_generic); __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); // ebx: base pointer of external storage switch (elements_kind) { case EXTERNAL_BYTE_ELEMENTS: - __ SmiUntag(ecx); // Untag the index. - __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); + __ SmiUntag(eax); // Untag the index. + __ movsx_b(eax, Operand(ebx, eax, times_1, 0)); break; case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS: - __ SmiUntag(ecx); // Untag the index. - __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); + __ SmiUntag(eax); // Untag the index. + __ movzx_b(eax, Operand(ebx, eax, times_1, 0)); break; case EXTERNAL_SHORT_ELEMENTS: - __ movsx_w(eax, Operand(ebx, ecx, times_1, 0)); + __ movsx_w(eax, Operand(ebx, eax, times_1, 0)); break; case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - __ movzx_w(eax, Operand(ebx, ecx, times_1, 0)); + __ movzx_w(eax, Operand(ebx, eax, times_1, 0)); break; case EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS: - __ mov(eax, Operand(ebx, ecx, times_2, 0)); + __ mov(ecx, Operand(ebx, eax, times_2, 0)); break; case EXTERNAL_FLOAT_ELEMENTS: - __ fld_s(Operand(ebx, ecx, times_2, 0)); + __ fld_s(Operand(ebx, eax, times_2, 0)); break; case EXTERNAL_DOUBLE_ELEMENTS: - __ fld_d(Operand(ebx, ecx, times_4, 0)); + __ fld_d(Operand(ebx, eax, times_4, 0)); break; default: UNREACHABLE(); @@ -3403,7 +3372,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( } // For integer array types: - // eax: value + // ecx: value // For floating-point array type: // FP(0): value @@ -3414,17 +3383,18 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // it to a HeapNumber. Label box_int; if (elements_kind == EXTERNAL_INT_ELEMENTS) { - __ cmp(eax, 0xc0000000); + __ cmp(ecx, 0xC0000000); __ j(sign, &box_int); } else { ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. - __ test(eax, Immediate(0xc0000000)); + __ test(ecx, Immediate(0xC0000000)); __ j(not_zero, &box_int); } + __ mov(eax, ecx); __ SmiTag(eax); __ ret(0); @@ -3433,31 +3403,33 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // Allocate a HeapNumber for the int and perform int-to-double // conversion. if (elements_kind == EXTERNAL_INT_ELEMENTS) { - __ push(eax); + __ push(ecx); __ fild_s(Operand(esp, 0)); - __ pop(eax); + __ pop(ecx); } else { ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); // Need to zero-extend the value. // There's no fild variant for unsigned values, so zero-extend // to a 64-bit int manually. __ push(Immediate(0)); - __ push(eax); + __ push(ecx); __ fild_d(Operand(esp, 0)); - __ pop(eax); - __ pop(eax); + __ pop(ecx); + __ pop(ecx); } // FP(0): value - __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation); + __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); // Set the value. + __ mov(eax, ecx); __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. - __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation); + __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); // Set the value. + __ mov(eax, ecx); __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ ret(0); } else { @@ -3477,7 +3449,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3486,7 +3458,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ jmp(ic, RelocInfo::CODE_TARGET); // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3503,8 +3475,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( MacroAssembler* masm, ElementsKind elements_kind) { // ----------- S t a t e ------------- - // -- eax : value - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3513,8 +3484,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(ecx, &miss_force_generic); // Check that the index is in range. __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); @@ -3609,39 +3580,12 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // (code-stubs-ia32.cc) is roughly what is needed here though the // conversion failure case does not need to be handled. if (CpuFeatures::IsSupported(SSE2)) { - if ((elements_kind == EXTERNAL_INT_ELEMENTS || - elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) && - CpuFeatures::IsSupported(SSE3)) { - CpuFeatures::Scope scope(SSE3); - // fisttp stores values as signed integers. To represent the - // entire range of int and unsigned int arrays, store as a - // 64-bit int and discard the high 32 bits. - __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); - __ sub(esp, Immediate(2 * kPointerSize)); - __ fisttp_d(Operand(esp, 0)); - - // If conversion failed (NaN, infinity, or a number outside - // signed int64 range), the result is 0x8000000000000000, and - // we must handle this case in the runtime. - Label ok; - __ cmp(Operand(esp, kPointerSize), Immediate(0x80000000u)); - __ j(not_equal, &ok); - __ cmp(Operand(esp, 0), Immediate(0)); - __ j(not_equal, &ok); - __ add(esp, Immediate(2 * kPointerSize)); // Restore the stack. - __ jmp(&slow); - - __ bind(&ok); - __ pop(ebx); - __ add(esp, Immediate(kPointerSize)); - __ mov(Operand(edi, ecx, times_2, 0), ebx); - } else { + if (elements_kind != EXTERNAL_INT_ELEMENTS && + elements_kind != EXTERNAL_UNSIGNED_INT_ELEMENTS) { ASSERT(CpuFeatures::IsSupported(SSE2)); CpuFeatures::Scope scope(SSE2); __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset)); - __ cmp(ebx, 0x80000000u); - __ j(equal, &slow); - // ebx: untagged integer value + // ecx: untagged integer value switch (elements_kind) { case EXTERNAL_PIXEL_ELEMENTS: __ ClampUint8(ebx); @@ -3655,14 +3599,41 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ mov_w(Operand(edi, ecx, times_1, 0), ebx); break; - case EXTERNAL_INT_ELEMENTS: - case EXTERNAL_UNSIGNED_INT_ELEMENTS: - __ mov(Operand(edi, ecx, times_2, 0), ebx); - break; default: UNREACHABLE(); break; } + } else { + if (CpuFeatures::IsSupported(SSE3)) { + CpuFeatures::Scope scope(SSE3); + // fisttp stores values as signed integers. To represent the + // entire range of int and unsigned int arrays, store as a + // 64-bit int and discard the high 32 bits. + // If the value is NaN or +/-infinity, the result is 0x80000000, + // which is automatically zero when taken mod 2^n, n < 32. + __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); + __ sub(esp, Immediate(2 * kPointerSize)); + __ fisttp_d(Operand(esp, 0)); + __ pop(ebx); + __ add(esp, Immediate(kPointerSize)); + } else { + ASSERT(CpuFeatures::IsSupported(SSE2)); + CpuFeatures::Scope scope(SSE2); + // We can easily implement the correct rounding behavior for the + // range [0, 2^31-1]. For the time being, to keep this code simple, + // make the slow runtime call for values outside this range. + // Note: we could do better for signed int arrays. + __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); + // We will need the key if we have to make the slow runtime call. + __ push(ebx); + __ LoadPowerOf2(xmm1, ebx, 31); + __ pop(ebx); + __ ucomisd(xmm1, xmm0); + __ j(above_equal, &slow); + __ cvttsd2si(ebx, Operand(xmm0)); + } + // ebx: untagged integer value + __ mov(Operand(edi, ecx, times_2, 0), ebx); } __ ret(0); // Return original value. } @@ -3700,7 +3671,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3709,19 +3680,19 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(eax, &miss_force_generic); // Get the elements array. - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); - __ AssertFastElements(eax); + __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); + __ AssertFastElements(ecx); // Check that the key is within bounds. - __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); + __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); __ j(above_equal, &miss_force_generic); // Load the result and make sure it's not the hole. - __ mov(ebx, Operand(eax, ecx, times_2, + __ mov(ebx, Operand(ecx, eax, times_2, FixedArray::kHeaderSize - kHeapObjectTag)); __ cmp(ebx, masm->isolate()->factory()->the_hole_value()); __ j(equal, &miss_force_generic); @@ -3738,7 +3709,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- ecx : key + // -- eax : key // -- edx : receiver // -- esp[0] : return address // ----------------------------------- @@ -3747,38 +3718,39 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(eax, &miss_force_generic); // Get the elements array. - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); - __ AssertFastElements(eax); + __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); + __ AssertFastElements(ecx); // Check that the key is within bounds. - __ cmp(ecx, FieldOperand(eax, FixedDoubleArray::kLengthOffset)); + __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset)); __ j(above_equal, &miss_force_generic); // Check for the hole uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); - __ cmp(FieldOperand(eax, ecx, times_4, offset), Immediate(kHoleNanUpper32)); + __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32)); __ j(equal, &miss_force_generic); // Always allocate a heap number for the result. if (CpuFeatures::IsSupported(SSE2)) { CpuFeatures::Scope use_sse2(SSE2); - __ movdbl(xmm0, FieldOperand(eax, ecx, times_4, + __ movdbl(xmm0, FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize)); } else { - __ fld_d(FieldOperand(eax, ecx, times_4, FixedDoubleArray::kHeaderSize)); + __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize)); } - __ AllocateHeapNumber(eax, ebx, edi, &slow_allocate_heapnumber); + __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber); // Set the value. if (CpuFeatures::IsSupported(SSE2)) { CpuFeatures::Scope use_sse2(SSE2); - __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); + __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); } else { - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); + __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset)); } + __ mov(eax, ecx); __ ret(0); __ bind(&slow_allocate_heapnumber); @@ -3815,8 +3787,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(ecx, &miss_force_generic); if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { __ JumpIfNotSmi(eax, &transition_elements_kind); @@ -3970,8 +3942,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(ecx, &miss_force_generic); // Get the elements array. __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); @@ -4032,7 +4004,6 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements); __ AllocateInNewSpace(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT); - // Restore the key, which is known to be the array length. __ mov(ecx, Immediate(0)); diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc index 643fa88413..b8d4b40bc9 100644 --- a/deps/v8/src/ic.cc +++ b/deps/v8/src/ic.cc @@ -1053,33 +1053,18 @@ Handle<Code> KeyedLoadIC::ComputePolymorphicStub( } -static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { - // This helper implements a few common fast cases for converting - // non-smi keys of keyed loads/stores to a smi or a string. - if (key->IsHeapNumber()) { - double value = Handle<HeapNumber>::cast(key)->value(); - if (isnan(value)) { - key = isolate->factory()->nan_symbol(); - } else { - int int_value = FastD2I(value); - if (value == int_value && Smi::IsValid(int_value)) { - key = Handle<Smi>(Smi::FromInt(int_value)); - } - } - } else if (key->IsUndefined()) { - key = isolate->factory()->undefined_symbol(); - } - return key; -} - - MaybeObject* KeyedLoadIC::Load(State state, Handle<Object> object, Handle<Object> key, bool force_generic_stub) { - // Check for values that can be converted into a symbol directly or - // is representable as a smi. - key = TryConvertKey(key, isolate()); + // Check for values that can be converted into a symbol. + // TODO(1295): Remove this code. + if (key->IsHeapNumber() && + isnan(Handle<HeapNumber>::cast(key)->value())) { + key = isolate()->factory()->nan_symbol(); + } else if (key->IsUndefined()) { + key = isolate()->factory()->undefined_symbol(); + } if (key->IsSymbol()) { Handle<String> name = Handle<String>::cast(key); @@ -1776,10 +1761,6 @@ MaybeObject* KeyedStoreIC::Store(State state, Handle<Object> key, Handle<Object> value, bool force_generic) { - // Check for values that can be converted into a symbol directly or - // is representable as a smi. - key = TryConvertKey(key, isolate()); - if (key->IsSymbol()) { Handle<String> name = Handle<String>::cast(key); diff --git a/deps/v8/src/incremental-marking.cc b/deps/v8/src/incremental-marking.cc index 2413b67803..7bbd5218b1 100644 --- a/deps/v8/src/incremental-marking.cc +++ b/deps/v8/src/incremental-marking.cc @@ -830,19 +830,6 @@ void IncrementalMarking::Step(intptr_t allocated_bytes, MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache()); VisitGlobalContext(ctx, &marking_visitor); - } else if (map->instance_type() == JS_FUNCTION_TYPE) { - marking_visitor.VisitPointers( - HeapObject::RawField(obj, JSFunction::kPropertiesOffset), - HeapObject::RawField(obj, JSFunction::kCodeEntryOffset)); - - marking_visitor.VisitCodeEntry( - obj->address() + JSFunction::kCodeEntryOffset); - - marking_visitor.VisitPointers( - HeapObject::RawField(obj, - JSFunction::kCodeEntryOffset + kPointerSize), - HeapObject::RawField(obj, - JSFunction::kNonWeakFieldsEndOffset)); } else { obj->IterateBody(map->instance_type(), size, &marking_visitor); } diff --git a/deps/v8/src/interface.cc b/deps/v8/src/interface.cc index 7836110e5f..e344b86150 100644 --- a/deps/v8/src/interface.cc +++ b/deps/v8/src/interface.cc @@ -79,7 +79,7 @@ void Interface::DoAdd( PrintF("%*sthis = ", Nesting::current(), ""); this->Print(Nesting::current()); PrintF("%*s%s : ", Nesting::current(), "", - (*static_cast<String**>(name))->ToAsciiArray()); + (*reinterpret_cast<String**>(name))->ToAsciiArray()); interface->Print(Nesting::current()); } #endif @@ -97,7 +97,7 @@ void Interface::DoAdd( #ifdef DEBUG Nesting nested; #endif - static_cast<Interface*>(p->value)->Unify(interface, ok); + reinterpret_cast<Interface*>(p->value)->Unify(interface, ok); } #ifdef DEBUG @@ -180,15 +180,6 @@ void Interface::DoUnify(Interface* that, bool* ok) { return; } - // Merge instance. - if (!that->instance_.is_null()) { - if (!this->instance_.is_null() && *this->instance_ != *that->instance_) { - *ok = false; - return; - } - this->instance_ = that->instance_; - } - // Merge interfaces. this->flags_ |= that->flags_; that->forward_ = this; diff --git a/deps/v8/src/interface.h b/deps/v8/src/interface.h index 580f082b46..c2991cbd63 100644 --- a/deps/v8/src/interface.h +++ b/deps/v8/src/interface.h @@ -86,12 +86,6 @@ class Interface : public ZoneObject { if (*ok) Chase()->flags_ |= MODULE; } - // Set associated instance object. - void MakeSingleton(Handle<JSModule> instance, bool* ok) { - *ok = IsModule() && Chase()->instance_.is_null(); - if (*ok) Chase()->instance_ = instance; - } - // Do not allow any further refinements, directly or through unification. void Freeze(bool* ok) { *ok = IsValue() || IsModule(); @@ -101,6 +95,9 @@ class Interface : public ZoneObject { // --------------------------------------------------------------------------- // Accessors. + // Look up an exported name. Returns NULL if not (yet) defined. + Interface* Lookup(Handle<String> name); + // Check whether this is still a fully undetermined type. bool IsUnknown() { return Chase()->flags_ == NONE; } @@ -113,42 +110,6 @@ class Interface : public ZoneObject { // Check whether this is closed (i.e. fully determined). bool IsFrozen() { return Chase()->flags_ & FROZEN; } - Handle<JSModule> Instance() { return Chase()->instance_; } - - // Look up an exported name. Returns NULL if not (yet) defined. - Interface* Lookup(Handle<String> name); - - // --------------------------------------------------------------------------- - // Iterators. - - // Use like: - // for (auto it = interface->iterator(); !it.done(); it.Advance()) { - // ... it.name() ... it.interface() ... - // } - class Iterator { - public: - bool done() const { return entry_ == NULL; } - Handle<String> name() const { - ASSERT(!done()); - return Handle<String>(*static_cast<String**>(entry_->key)); - } - Interface* interface() const { - ASSERT(!done()); - return static_cast<Interface*>(entry_->value); - } - void Advance() { entry_ = exports_->Next(entry_); } - - private: - friend class Interface; - explicit Iterator(const ZoneHashMap* exports) - : exports_(exports), entry_(exports ? exports->Start() : NULL) {} - - const ZoneHashMap* exports_; - ZoneHashMap::Entry* entry_; - }; - - Iterator iterator() const { return Iterator(this->exports_); } - // --------------------------------------------------------------------------- // Debugging. #ifdef DEBUG @@ -168,7 +129,6 @@ class Interface : public ZoneObject { int flags_; Interface* forward_; // Unification link ZoneHashMap* exports_; // Module exports and their types (allocated lazily) - Handle<JSModule> instance_; explicit Interface(int flags) : flags_(flags), diff --git a/deps/v8/src/interpreter-irregexp.cc b/deps/v8/src/interpreter-irregexp.cc index 3a92b84554..b337e88452 100644 --- a/deps/v8/src/interpreter-irregexp.cc +++ b/deps/v8/src/interpreter-irregexp.cc @@ -33,9 +33,8 @@ #include "utils.h" #include "ast.h" #include "bytecodes-irregexp.h" -#include "interpreter-irregexp.h" #include "jsregexp.h" -#include "regexp-macro-assembler.h" +#include "interpreter-irregexp.h" namespace v8 { namespace internal { @@ -450,37 +449,6 @@ static RegExpImpl::IrregexpResult RawMatch(Isolate* isolate, } break; } - BYTECODE(CHECK_CHAR_IN_RANGE) { - uint32_t from = Load16Aligned(pc + 4); - uint32_t to = Load16Aligned(pc + 6); - if (from <= current_char && current_char <= to) { - pc = code_base + Load32Aligned(pc + 8); - } else { - pc += BC_CHECK_CHAR_IN_RANGE_LENGTH; - } - break; - } - BYTECODE(CHECK_CHAR_NOT_IN_RANGE) { - uint32_t from = Load16Aligned(pc + 4); - uint32_t to = Load16Aligned(pc + 6); - if (from > current_char || current_char > to) { - pc = code_base + Load32Aligned(pc + 8); - } else { - pc += BC_CHECK_CHAR_NOT_IN_RANGE_LENGTH; - } - break; - } - BYTECODE(CHECK_BIT_IN_TABLE) { - int mask = RegExpMacroAssembler::kTableMask; - byte b = pc[8 + ((current_char & mask) >> kBitsPerByteLog2)]; - int bit = (current_char & (kBitsPerByte - 1)); - if ((b & (1 << bit)) != 0) { - pc = code_base + Load32Aligned(pc + 4); - } else { - pc += BC_CHECK_BIT_IN_TABLE_LENGTH; - } - break; - } BYTECODE(CHECK_LT) { uint32_t limit = (insn >> BYTECODE_SHIFT); if (current_char < limit) { @@ -520,6 +488,59 @@ static RegExpImpl::IrregexpResult RawMatch(Isolate* isolate, pc += BC_CHECK_REGISTER_EQ_POS_LENGTH; } break; + BYTECODE(LOOKUP_MAP1) { + // Look up character in a bitmap. If we find a 0, then jump to the + // location at pc + 8. Otherwise fall through! + int index = current_char - (insn >> BYTECODE_SHIFT); + byte map = code_base[Load32Aligned(pc + 4) + (index >> 3)]; + map = ((map >> (index & 7)) & 1); + if (map == 0) { + pc = code_base + Load32Aligned(pc + 8); + } else { + pc += BC_LOOKUP_MAP1_LENGTH; + } + break; + } + BYTECODE(LOOKUP_MAP2) { + // Look up character in a half-nibble map. If we find 00, then jump to + // the location at pc + 8. If we find 01 then jump to location at + // pc + 11, etc. + int index = (current_char - (insn >> BYTECODE_SHIFT)) << 1; + byte map = code_base[Load32Aligned(pc + 3) + (index >> 3)]; + map = ((map >> (index & 7)) & 3); + if (map < 2) { + if (map == 0) { + pc = code_base + Load32Aligned(pc + 8); + } else { + pc = code_base + Load32Aligned(pc + 12); + } + } else { + if (map == 2) { + pc = code_base + Load32Aligned(pc + 16); + } else { + pc = code_base + Load32Aligned(pc + 20); + } + } + break; + } + BYTECODE(LOOKUP_MAP8) { + // Look up character in a byte map. Use the byte as an index into a + // table that follows this instruction immediately. + int index = current_char - (insn >> BYTECODE_SHIFT); + byte map = code_base[Load32Aligned(pc + 4) + index]; + const byte* new_pc = code_base + Load32Aligned(pc + 8) + (map << 2); + pc = code_base + Load32Aligned(new_pc); + break; + } + BYTECODE(LOOKUP_HI_MAP8) { + // Look up high byte of this character in a byte map. Use the byte as + // an index into a table that follows this instruction immediately. + int index = (current_char >> 8) - (insn >> BYTECODE_SHIFT); + byte map = code_base[Load32Aligned(pc + 4) + index]; + const byte* new_pc = code_base + Load32Aligned(pc + 8) + (map << 2); + pc = code_base + Load32Aligned(new_pc); + break; + } BYTECODE(CHECK_NOT_REGS_EQUAL) if (registers[insn >> BYTECODE_SHIFT] == registers[Load32Aligned(pc + 4)]) { diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index 0c97abd89e..e80512239d 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -1430,7 +1430,6 @@ void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) { Isolate::Isolate() : state_(UNINITIALIZED), - embedder_data_(NULL), entry_stack_(NULL), stack_trace_nesting_level_(0), incomplete_message_(NULL), @@ -1473,6 +1472,7 @@ Isolate::Isolate() string_tracker_(NULL), regexp_stack_(NULL), date_cache_(NULL), + embedder_data_(NULL), context_exit_happened_(false) { TRACE_ISOLATE(constructor); @@ -1857,13 +1857,6 @@ bool Isolate::Init(Deserializer* des) { LOG(this, LogCompiledFunctions()); } - CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, state_)), - Internals::kIsolateStateOffset); - CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)), - Internals::kIsolateEmbedderDataOffset); - CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)), - Internals::kIsolateRootsOffset); - state_ = INITIALIZED; time_millis_at_init_ = OS::TimeCurrentMillis(); return true; diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h index f1c9b3ccfa..2ff131840f 100644 --- a/deps/v8/src/isolate.h +++ b/deps/v8/src/isolate.h @@ -422,7 +422,7 @@ class Isolate { enum AddressId { #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address, FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM) -#undef DECLARE_ENUM +#undef C kIsolateAddressCount }; @@ -1038,18 +1038,6 @@ class Isolate { friend struct GlobalState; friend struct InitializeGlobalState; - enum State { - UNINITIALIZED, // Some components may not have been allocated. - INITIALIZED // All components are fully initialized. - }; - - // These fields are accessed through the API, offsets must be kept in sync - // with v8::internal::Internals (in include/v8.h) constants. This is also - // verified in Isolate::Init() using runtime checks. - State state_; // Will be padded to kApiPointerSize. - void* embedder_data_; - Heap heap_; - // The per-process lock should be acquired before the ThreadDataTable is // modified. class ThreadDataTable { @@ -1107,6 +1095,14 @@ class Isolate { static void SetIsolateThreadLocals(Isolate* isolate, PerIsolateThreadData* data); + enum State { + UNINITIALIZED, // Some components may not have been allocated. + INITIALIZED // All components are fully initialized. + }; + + State state_; + EntryStackItem* entry_stack_; + // Allocate and insert PerIsolateThreadData into the ThreadDataTable // (regardless of whether such data already exists). PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id); @@ -1150,13 +1146,13 @@ class Isolate { // the Error object. bool IsErrorObject(Handle<Object> obj); - EntryStackItem* entry_stack_; int stack_trace_nesting_level_; StringStream* incomplete_message_; // The preallocated memory thread singleton. PreallocatedMemoryThread* preallocated_memory_thread_; Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT NoAllocationStringAllocator* preallocated_message_space_; + Bootstrapper* bootstrapper_; RuntimeProfiler* runtime_profiler_; CompilationCache* compilation_cache_; @@ -1165,6 +1161,7 @@ class Isolate { Mutex* break_access_; Atomic32 debugger_initialized_; Mutex* debugger_access_; + Heap heap_; Logger* logger_; StackGuard stack_guard_; StatsTable* stats_table_; @@ -1205,8 +1202,11 @@ class Isolate { unibrow::Mapping<unibrow::Ecma262Canonicalize> regexp_macro_assembler_canonicalize_; RegExpStack* regexp_stack_; + DateCache* date_cache_; + unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_; + void* embedder_data_; // The garbage collector should be a little more aggressive when it knows // that a context was recently exited. diff --git a/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc index 2e9bda1d25..8ccbae49ce 100644 --- a/deps/v8/src/jsregexp.cc +++ b/deps/v8/src/jsregexp.cc @@ -108,60 +108,6 @@ static inline void ThrowRegExpException(Handle<JSRegExp> re, } -ContainedInLattice AddRange(ContainedInLattice containment, - const int* ranges, - int ranges_length, - Interval new_range) { - ASSERT((ranges_length & 1) == 1); - ASSERT(ranges[ranges_length - 1] == String::kMaxUtf16CodeUnit + 1); - if (containment == kLatticeUnknown) return containment; - bool inside = false; - int last = 0; - for (int i = 0; i < ranges_length; inside = !inside, last = ranges[i], i++) { - // Consider the range from last to ranges[i]. - // We haven't got to the new range yet. - if (ranges[i] <= new_range.from()) continue; - // New range is wholly inside last-ranges[i]. Note that new_range.to() is - // inclusive, but the values in ranges are not. - if (last <= new_range.from() && new_range.to() < ranges[i]) { - return Combine(containment, inside ? kLatticeIn : kLatticeOut); - } - return kLatticeUnknown; - } - return containment; -} - - -// More makes code generation slower, less makes V8 benchmark score lower. -const int kMaxLookaheadForBoyerMoore = 8; -// In a 3-character pattern you can maximally step forwards 3 characters -// at a time, which is not always enough to pay for the extra logic. -const int kPatternTooShortForBoyerMoore = 2; - - -// Identifies the sort of regexps where the regexp engine is faster -// than the code used for atom matches. -static bool HasFewDifferentCharacters(Handle<String> pattern) { - int length = Min(kMaxLookaheadForBoyerMoore, pattern->length()); - if (length <= kPatternTooShortForBoyerMoore) return false; - const int kMod = 128; - bool character_found[kMod]; - int different = 0; - memset(&character_found[0], 0, sizeof(character_found)); - for (int i = 0; i < length; i++) { - int ch = (pattern->Get(i) & (kMod - 1)); - if (!character_found[ch]) { - character_found[ch] = true; - different++; - // We declare a regexp low-alphabet if it has at least 3 times as many - // characters as it has different characters. - if (different * 3 > length) return false; - } - } - return true; -} - - // Generic RegExp methods. Dispatches to implementation specific methods. @@ -195,14 +141,9 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, return Handle<Object>::null(); } - bool has_been_compiled = false; - - if (parse_result.simple && - !flags.is_ignore_case() && - !HasFewDifferentCharacters(pattern)) { + if (parse_result.simple && !flags.is_ignore_case()) { // Parse-tree is a single atom that is equal to the pattern. AtomCompile(re, pattern, flags, pattern); - has_been_compiled = true; } else if (parse_result.tree->IsAtom() && !flags.is_ignore_case() && parse_result.capture_count == 0) { @@ -210,12 +151,8 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, Vector<const uc16> atom_pattern = atom->data(); Handle<String> atom_string = isolate->factory()->NewStringFromTwoByte(atom_pattern); - if (!HasFewDifferentCharacters(atom_string)) { - AtomCompile(re, pattern, flags, atom_string); - has_been_compiled = true; - } - } - if (!has_been_compiled) { + AtomCompile(re, pattern, flags, atom_string); + } else { IrregexpInitialize(re, pattern, flags, parse_result.capture_count); } ASSERT(re->data()->IsFixedArray()); @@ -343,8 +280,7 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, // from the source pattern. // If compilation fails, an exception is thrown and this function // returns false. -bool RegExpImpl::EnsureCompiledIrregexp( - Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) { +bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) { Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii)); #ifdef V8_INTERPRETED_REGEXP if (compiled_code->IsByteArray()) return true; @@ -360,7 +296,7 @@ bool RegExpImpl::EnsureCompiledIrregexp( ASSERT(compiled_code->IsSmi()); return true; } - return CompileIrregexp(re, sample_subject, is_ascii); + return CompileIrregexp(re, is_ascii); } @@ -380,9 +316,7 @@ static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re, } -bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, - Handle<String> sample_subject, - bool is_ascii) { +bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) { // Compile the RegExp. Isolate* isolate = re->GetIsolate(); ZoneScope zone_scope(isolate, DELETE_ON_EXIT); @@ -431,7 +365,6 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, flags.is_ignore_case(), flags.is_multiline(), pattern, - sample_subject, is_ascii); if (result.error_message != NULL) { // Unable to compile regexp. @@ -502,7 +435,7 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp, // Check the asciiness of the underlying storage. bool is_ascii = subject->IsAsciiRepresentationUnderneath(); - if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1; + if (!EnsureCompiledIrregexp(regexp, is_ascii)) return -1; #ifdef V8_INTERPRETED_REGEXP // Byte-code regexp needs space allocated for all its registers. @@ -533,7 +466,7 @@ RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce( #ifndef V8_INTERPRETED_REGEXP ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2); do { - EnsureCompiledIrregexp(regexp, subject, is_ascii); + EnsureCompiledIrregexp(regexp, is_ascii); Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate); NativeRegExpMacroAssembler::Result res = NativeRegExpMacroAssembler::Match(code, @@ -851,53 +784,6 @@ DispatchTable* ChoiceNode::GetTable(bool ignore_case) { } -class FrequencyCollator { - public: - FrequencyCollator() : total_samples_(0) { - for (int i = 0; i < RegExpMacroAssembler::kTableSize; i++) { - frequencies_[i] = CharacterFrequency(i); - } - } - - void CountCharacter(int character) { - int index = (character & RegExpMacroAssembler::kTableMask); - frequencies_[index].Increment(); - total_samples_++; - } - - // Does not measure in percent, but rather per-128 (the table size from the - // regexp macro assembler). - int Frequency(int in_character) { - ASSERT((in_character & RegExpMacroAssembler::kTableMask) == in_character); - if (total_samples_ < 1) return 1; // Division by zero. - int freq_in_per128 = - (frequencies_[in_character].counter() * 128) / total_samples_; - return freq_in_per128; - } - - private: - class CharacterFrequency { - public: - CharacterFrequency() : counter_(0), character_(-1) { } - explicit CharacterFrequency(int character) - : counter_(0), character_(character) { } - - void Increment() { counter_++; } - int counter() { return counter_; } - int character() { return character_; } - - private: - int counter_; - int character_; - }; - - - private: - CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize]; - int total_samples_; -}; - - class RegExpCompiler { public: RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii); @@ -933,7 +819,6 @@ class RegExpCompiler { inline bool ignore_case() { return ignore_case_; } inline bool ascii() { return ascii_; } - FrequencyCollator* frequency_collator() { return &frequency_collator_; } int current_expansion_factor() { return current_expansion_factor_; } void set_current_expansion_factor(int value) { @@ -952,7 +837,6 @@ class RegExpCompiler { bool ascii_; bool reg_exp_too_big_; int current_expansion_factor_; - FrequencyCollator frequency_collator_; }; @@ -981,8 +865,7 @@ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii) ignore_case_(ignore_case), ascii_(ascii), reg_exp_too_big_(false), - current_expansion_factor_(1), - frequency_collator_() { + current_expansion_factor_(1) { accept_ = new EndNode(EndNode::ACCEPT); ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); } @@ -1651,357 +1534,6 @@ static inline bool EmitAtomLetter(Isolate* isolate, } -static void EmitBoundaryTest(RegExpMacroAssembler* masm, - int border, - Label* fall_through, - Label* above_or_equal, - Label* below) { - if (below != fall_through) { - masm->CheckCharacterLT(border, below); - if (above_or_equal != fall_through) masm->GoTo(above_or_equal); - } else { - masm->CheckCharacterGT(border - 1, above_or_equal); - } -} - - -static void EmitDoubleBoundaryTest(RegExpMacroAssembler* masm, - int first, - int last, - Label* fall_through, - Label* in_range, - Label* out_of_range) { - if (in_range == fall_through) { - if (first == last) { - masm->CheckNotCharacter(first, out_of_range); - } else { - masm->CheckCharacterNotInRange(first, last, out_of_range); - } - } else { - if (first == last) { - masm->CheckCharacter(first, in_range); - } else { - masm->CheckCharacterInRange(first, last, in_range); - } - if (out_of_range != fall_through) masm->GoTo(out_of_range); - } -} - - -// even_label is for ranges[i] to ranges[i + 1] where i - start_index is even. -// odd_label is for ranges[i] to ranges[i + 1] where i - start_index is odd. -static void EmitUseLookupTable( - RegExpMacroAssembler* masm, - ZoneList<int>* ranges, - int start_index, - int end_index, - int min_char, - Label* fall_through, - Label* even_label, - Label* odd_label) { - static const int kSize = RegExpMacroAssembler::kTableSize; - static const int kMask = RegExpMacroAssembler::kTableMask; - - int base = (min_char & ~kMask); - USE(base); - - // Assert that everything is on one kTableSize page. - for (int i = start_index; i <= end_index; i++) { - ASSERT_EQ(ranges->at(i) & ~kMask, base); - } - ASSERT(start_index == 0 || (ranges->at(start_index - 1) & ~kMask) <= base); - - char templ[kSize]; - Label* on_bit_set; - Label* on_bit_clear; - int bit; - if (even_label == fall_through) { - on_bit_set = odd_label; - on_bit_clear = even_label; - bit = 1; - } else { - on_bit_set = even_label; - on_bit_clear = odd_label; - bit = 0; - } - for (int i = 0; i < (ranges->at(start_index) & kMask) && i < kSize; i++) { - templ[i] = bit; - } - int j = 0; - bit ^= 1; - for (int i = start_index; i < end_index; i++) { - for (j = (ranges->at(i) & kMask); j < (ranges->at(i + 1) & kMask); j++) { - templ[j] = bit; - } - bit ^= 1; - } - for (int i = j; i < kSize; i++) { - templ[i] = bit; - } - // TODO(erikcorry): Cache these. - Handle<ByteArray> ba = FACTORY->NewByteArray(kSize, TENURED); - for (int i = 0; i < kSize; i++) { - ba->set(i, templ[i]); - } - masm->CheckBitInTable(ba, on_bit_set); - if (on_bit_clear != fall_through) masm->GoTo(on_bit_clear); -} - - -static void CutOutRange(RegExpMacroAssembler* masm, - ZoneList<int>* ranges, - int start_index, - int end_index, - int cut_index, - Label* even_label, - Label* odd_label) { - bool odd = (((cut_index - start_index) & 1) == 1); - Label* in_range_label = odd ? odd_label : even_label; - Label dummy; - EmitDoubleBoundaryTest(masm, - ranges->at(cut_index), - ranges->at(cut_index + 1) - 1, - &dummy, - in_range_label, - &dummy); - ASSERT(!dummy.is_linked()); - // Cut out the single range by rewriting the array. This creates a new - // range that is a merger of the two ranges on either side of the one we - // are cutting out. The oddity of the labels is preserved. - for (int j = cut_index; j > start_index; j--) { - ranges->at(j) = ranges->at(j - 1); - } - for (int j = cut_index + 1; j < end_index; j++) { - ranges->at(j) = ranges->at(j + 1); - } -} - - -// Unicode case. Split the search space into kSize spaces that are handled -// with recursion. -static void SplitSearchSpace(ZoneList<int>* ranges, - int start_index, - int end_index, - int* new_start_index, - int* new_end_index, - int* border) { - static const int kSize = RegExpMacroAssembler::kTableSize; - static const int kMask = RegExpMacroAssembler::kTableMask; - - int first = ranges->at(start_index); - int last = ranges->at(end_index) - 1; - - *new_start_index = start_index; - *border = (ranges->at(start_index) & ~kMask) + kSize; - while (*new_start_index < end_index) { - if (ranges->at(*new_start_index) > *border) break; - (*new_start_index)++; - } - // new_start_index is the index of the first edge that is beyond the - // current kSize space. - - // For very large search spaces we do a binary chop search of the non-ASCII - // space instead of just going to the end of the current kSize space. The - // heuristics are complicated a little by the fact that any 128-character - // encoding space can be quickly tested with a table lookup, so we don't - // wish to do binary chop search at a smaller granularity than that. A - // 128-character space can take up a lot of space in the ranges array if, - // for example, we only want to match every second character (eg. the lower - // case characters on some Unicode pages). - int binary_chop_index = (end_index + start_index) / 2; - // The first test ensures that we get to the code that handles the ASCII - // range with a single not-taken branch, speeding up this important - // character range (even non-ASCII charset-based text has spaces and - // punctuation). - if (*border - 1 > String::kMaxAsciiCharCode && // ASCII case. - end_index - start_index > (*new_start_index - start_index) * 2 && - last - first > kSize * 2 && - binary_chop_index > *new_start_index && - ranges->at(binary_chop_index) >= first + 2 * kSize) { - int scan_forward_for_section_border = binary_chop_index;; - int new_border = (ranges->at(binary_chop_index) | kMask) + 1; - - while (scan_forward_for_section_border < end_index) { - if (ranges->at(scan_forward_for_section_border) > new_border) { - *new_start_index = scan_forward_for_section_border; - *border = new_border; - break; - } - scan_forward_for_section_border++; - } - } - - ASSERT(*new_start_index > start_index); - *new_end_index = *new_start_index - 1; - if (ranges->at(*new_end_index) == *border) { - (*new_end_index)--; - } - if (*border >= ranges->at(end_index)) { - *border = ranges->at(end_index); - *new_start_index = end_index; // Won't be used. - *new_end_index = end_index - 1; - } -} - - -// Gets a series of segment boundaries representing a character class. If the -// character is in the range between an even and an odd boundary (counting from -// start_index) then go to even_label, otherwise go to odd_label. We already -// know that the character is in the range of min_char to max_char inclusive. -// Either label can be NULL indicating backtracking. Either label can also be -// equal to the fall_through label. -static void GenerateBranches(RegExpMacroAssembler* masm, - ZoneList<int>* ranges, - int start_index, - int end_index, - uc16 min_char, - uc16 max_char, - Label* fall_through, - Label* even_label, - Label* odd_label) { - int first = ranges->at(start_index); - int last = ranges->at(end_index) - 1; - - ASSERT_LT(min_char, first); - - // Just need to test if the character is before or on-or-after - // a particular character. - if (start_index == end_index) { - EmitBoundaryTest(masm, first, fall_through, even_label, odd_label); - return; - } - - // Another almost trivial case: There is one interval in the middle that is - // different from the end intervals. - if (start_index + 1 == end_index) { - EmitDoubleBoundaryTest( - masm, first, last, fall_through, even_label, odd_label); - return; - } - - // It's not worth using table lookup if there are very few intervals in the - // character class. - if (end_index - start_index <= 6) { - // It is faster to test for individual characters, so we look for those - // first, then try arbitrary ranges in the second round. - static int kNoCutIndex = -1; - int cut = kNoCutIndex; - for (int i = start_index; i < end_index; i++) { - if (ranges->at(i) == ranges->at(i + 1) - 1) { - cut = i; - break; - } - } - if (cut == kNoCutIndex) cut = start_index; - CutOutRange( - masm, ranges, start_index, end_index, cut, even_label, odd_label); - ASSERT_GE(end_index - start_index, 2); - GenerateBranches(masm, - ranges, - start_index + 1, - end_index - 1, - min_char, - max_char, - fall_through, - even_label, - odd_label); - return; - } - - // If there are a lot of intervals in the regexp, then we will use tables to - // determine whether the character is inside or outside the character class. - static const int kBits = RegExpMacroAssembler::kTableSizeBits; - - if ((max_char >> kBits) == (min_char >> kBits)) { - EmitUseLookupTable(masm, - ranges, - start_index, - end_index, - min_char, - fall_through, - even_label, - odd_label); - return; - } - - if ((min_char >> kBits) != (first >> kBits)) { - masm->CheckCharacterLT(first, odd_label); - GenerateBranches(masm, - ranges, - start_index + 1, - end_index, - first, - max_char, - fall_through, - odd_label, - even_label); - return; - } - - int new_start_index = 0; - int new_end_index = 0; - int border = 0; - - SplitSearchSpace(ranges, - start_index, - end_index, - &new_start_index, - &new_end_index, - &border); - - Label handle_rest; - Label* above = &handle_rest; - if (border == last + 1) { - // We didn't find any section that started after the limit, so everything - // above the border is one of the terminal labels. - above = (end_index & 1) != (start_index & 1) ? odd_label : even_label; - ASSERT(new_end_index == end_index - 1); - } - - ASSERT_LE(start_index, new_end_index); - ASSERT_LE(new_start_index, end_index); - ASSERT_LT(start_index, new_start_index); - ASSERT_LT(new_end_index, end_index); - ASSERT(new_end_index + 1 == new_start_index || - (new_end_index + 2 == new_start_index && - border == ranges->at(new_end_index + 1))); - ASSERT_LT(min_char, border - 1); - ASSERT_LT(border, max_char); - ASSERT_LT(ranges->at(new_end_index), border); - ASSERT(border < ranges->at(new_start_index) || - (border == ranges->at(new_start_index) && - new_start_index == end_index && - new_end_index == end_index - 1 && - border == last + 1)); - ASSERT(new_start_index == 0 || border >= ranges->at(new_start_index - 1)); - - masm->CheckCharacterGT(border - 1, above); - Label dummy; - GenerateBranches(masm, - ranges, - start_index, - new_end_index, - min_char, - border - 1, - &dummy, - even_label, - odd_label); - if (handle_rest.is_linked()) { - masm->Bind(&handle_rest); - bool flip = (new_start_index & 1) != (start_index & 1); - GenerateBranches(masm, - ranges, - new_start_index, - end_index, - border, - max_char, - &dummy, - flip ? odd_label : even_label, - flip ? even_label : odd_label); - } -} - - static void EmitCharClass(RegExpMacroAssembler* macro_assembler, RegExpCharacterClass* cc, bool ascii, @@ -2010,10 +1542,6 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, bool check_offset, bool preloaded) { ZoneList<CharacterRange>* ranges = cc->ranges(); - if (!CharacterRange::IsCanonical(ranges)) { - CharacterRange::Canonicalize(ranges); - } - int max_char; if (ascii) { max_char = String::kMaxAsciiCharCode; @@ -2021,6 +1549,11 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, max_char = String::kMaxUtf16CodeUnit; } + Label success; + + Label* char_is_in_class = + cc->is_negated() ? on_failure : &success; + int range_count = ranges->length(); int last_valid_range = range_count - 1; @@ -2034,6 +1567,8 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, if (last_valid_range < 0) { if (!cc->is_negated()) { + // TODO(plesner): We can remove this when the node level does our + // ASCII optimizations for us. macro_assembler->GoTo(on_failure); } if (check_offset) { @@ -2043,18 +1578,6 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, } if (last_valid_range == 0 && - ranges->at(0).IsEverything(max_char)) { - if (cc->is_negated()) { - macro_assembler->GoTo(on_failure); - } else { - // This is a common case hit by non-anchored expressions. - if (check_offset) { - macro_assembler->CheckPosition(cp_offset, on_failure); - } - } - return; - } - if (last_valid_range == 0 && !cc->is_negated() && ranges->at(0).IsEverything(max_char)) { // This is a common case hit by non-anchored expressions. @@ -2074,43 +1597,64 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler, return; } + for (int i = 0; i < last_valid_range; i++) { + CharacterRange& range = ranges->at(i); + Label next_range; + uc16 from = range.from(); + uc16 to = range.to(); + if (from > max_char) { + continue; + } + if (to > max_char) to = max_char; + if (to == from) { + macro_assembler->CheckCharacter(to, char_is_in_class); + } else { + if (from != 0) { + macro_assembler->CheckCharacterLT(from, &next_range); + } + if (to != max_char) { + macro_assembler->CheckCharacterLT(to + 1, char_is_in_class); + } else { + macro_assembler->GoTo(char_is_in_class); + } + } + macro_assembler->Bind(&next_range); + } - // A new list with ascending entries. Each entry is a code unit - // where there is a boundary between code units that are part of - // the class and code units that are not. Normally we insert an - // entry at zero which goes to the failure label, but if there - // was already one there we fall through for success on that entry. - // Subsequent entries have alternating meaning (success/failure). - ZoneList<int>* range_boundaries = new ZoneList<int>(last_valid_range); + CharacterRange& range = ranges->at(last_valid_range); + uc16 from = range.from(); + uc16 to = range.to(); - bool zeroth_entry_is_failure = !cc->is_negated(); + if (to > max_char) to = max_char; + ASSERT(to >= from); - for (int i = 0; i <= last_valid_range; i++) { - CharacterRange& range = ranges->at(i); - if (range.from() == 0) { - ASSERT_EQ(i, 0); - zeroth_entry_is_failure = !zeroth_entry_is_failure; + if (to == from) { + if (cc->is_negated()) { + macro_assembler->CheckCharacter(to, on_failure); } else { - range_boundaries->Add(range.from()); + macro_assembler->CheckNotCharacter(to, on_failure); + } + } else { + if (from != 0) { + if (cc->is_negated()) { + macro_assembler->CheckCharacterLT(from, &success); + } else { + macro_assembler->CheckCharacterLT(from, on_failure); + } + } + if (to != String::kMaxUtf16CodeUnit) { + if (cc->is_negated()) { + macro_assembler->CheckCharacterLT(to + 1, on_failure); + } else { + macro_assembler->CheckCharacterGT(to, on_failure); + } + } else { + if (cc->is_negated()) { + macro_assembler->GoTo(on_failure); + } } - range_boundaries->Add(range.to() + 1); - } - int end_index = range_boundaries->length() - 1; - if (range_boundaries->at(end_index) > max_char) { - end_index--; } - - Label fall_through; - GenerateBranches(macro_assembler, - range_boundaries, - 0, // start_index. - end_index, - 0, // min_char. - max_char, - &fall_through, - zeroth_entry_is_failure ? &fall_through : on_failure, - zeroth_entry_is_failure ? on_failure : &fall_through); - macro_assembler->Bind(&fall_through); + macro_assembler->Bind(&success); } @@ -2173,21 +1717,6 @@ int ActionNode::EatsAtLeast(int still_to_find, } -void ActionNode::FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - if (type_ == BEGIN_SUBMATCH) { - bm->SetRest(offset); - } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { - on_success()->FillInBMInfo( - offset, recursion_depth + 1, budget - 1, bm, not_at_start); - } - SaveBMInfo(bm, not_at_start, offset); -} - - int AssertionNode::EatsAtLeast(int still_to_find, int recursion_depth, bool not_at_start) { @@ -2204,19 +1733,6 @@ int AssertionNode::EatsAtLeast(int still_to_find, } -void AssertionNode::FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - // Match the behaviour of EatsAtLeast on this node. - if (type() == AT_START && not_at_start) return; - on_success()->FillInBMInfo( - offset, recursion_depth + 1, budget - 1, bm, not_at_start); - SaveBMInfo(bm, not_at_start, offset); -} - - int BackReferenceNode::EatsAtLeast(int still_to_find, int recursion_depth, bool not_at_start) { @@ -2555,12 +2071,10 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details, } } ASSERT(characters_filled_in != details->characters()); - if (!details->cannot_match()) { - on_success()-> GetQuickCheckDetails(details, - compiler, - characters_filled_in, - true); - } + on_success()-> GetQuickCheckDetails(details, + compiler, + characters_filled_in, + true); } @@ -2638,148 +2152,6 @@ class VisitMarker { }; -RegExpNode* SeqRegExpNode::FilterASCII(int depth) { - if (info()->replacement_calculated) return replacement(); - if (depth < 0) return this; - ASSERT(!info()->visited); - VisitMarker marker(info()); - return FilterSuccessor(depth - 1); -} - - -RegExpNode* SeqRegExpNode::FilterSuccessor(int depth) { - RegExpNode* next = on_success_->FilterASCII(depth - 1); - if (next == NULL) return set_replacement(NULL); - on_success_ = next; - return set_replacement(this); -} - - -RegExpNode* TextNode::FilterASCII(int depth) { - if (info()->replacement_calculated) return replacement(); - if (depth < 0) return this; - ASSERT(!info()->visited); - VisitMarker marker(info()); - int element_count = elms_->length(); - for (int i = 0; i < element_count; i++) { - TextElement elm = elms_->at(i); - if (elm.type == TextElement::ATOM) { - Vector<const uc16> quarks = elm.data.u_atom->data(); - for (int j = 0; j < quarks.length(); j++) { - // We don't need special handling for case independence - // because of the rule that case independence cannot make - // a non-ASCII character match an ASCII character. - if (quarks[j] > String::kMaxAsciiCharCode) { - return set_replacement(NULL); - } - } - } else { - ASSERT(elm.type == TextElement::CHAR_CLASS); - RegExpCharacterClass* cc = elm.data.u_char_class; - ZoneList<CharacterRange>* ranges = cc->ranges(); - if (!CharacterRange::IsCanonical(ranges)) { - CharacterRange::Canonicalize(ranges); - } - // Now they are in order so we only need to look at the first. - int range_count = ranges->length(); - if (cc->is_negated()) { - if (range_count != 0 && - ranges->at(0).from() == 0 && - ranges->at(0).to() >= String::kMaxAsciiCharCode) { - return set_replacement(NULL); - } - } else { - if (range_count == 0 || - ranges->at(0).from() > String::kMaxAsciiCharCode) { - return set_replacement(NULL); - } - } - } - } - return FilterSuccessor(depth - 1); -} - - -RegExpNode* LoopChoiceNode::FilterASCII(int depth) { - if (info()->replacement_calculated) return replacement(); - if (depth < 0) return this; - if (info()->visited) return this; - { - VisitMarker marker(info()); - - RegExpNode* continue_replacement = continue_node_->FilterASCII(depth - 1); - // If we can't continue after the loop then there is no sense in doing the - // loop. - if (continue_replacement == NULL) return set_replacement(NULL); - } - - return ChoiceNode::FilterASCII(depth - 1); -} - - -RegExpNode* ChoiceNode::FilterASCII(int depth) { - if (info()->replacement_calculated) return replacement(); - if (depth < 0) return this; - if (info()->visited) return this; - VisitMarker marker(info()); - int choice_count = alternatives_->length(); - int surviving = 0; - RegExpNode* survivor = NULL; - for (int i = 0; i < choice_count; i++) { - GuardedAlternative alternative = alternatives_->at(i); - RegExpNode* replacement = alternative.node()->FilterASCII(depth - 1); - ASSERT(replacement != this); // No missing EMPTY_MATCH_CHECK. - if (replacement != NULL) { - alternatives_->at(i).set_node(replacement); - surviving++; - survivor = replacement; - } - } - if (surviving < 2) return set_replacement(survivor); - - set_replacement(this); - if (surviving == choice_count) { - return this; - } - // Only some of the nodes survived the filtering. We need to rebuild the - // alternatives list. - ZoneList<GuardedAlternative>* new_alternatives = - new ZoneList<GuardedAlternative>(surviving); - for (int i = 0; i < choice_count; i++) { - RegExpNode* replacement = - alternatives_->at(i).node()->FilterASCII(depth - 1); - if (replacement != NULL) { - alternatives_->at(i).set_node(replacement); - new_alternatives->Add(alternatives_->at(i)); - } - } - alternatives_ = new_alternatives; - return this; -} - - -RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) { - if (info()->replacement_calculated) return replacement(); - if (depth < 0) return this; - if (info()->visited) return this; - VisitMarker marker(info()); - // Alternative 0 is the negative lookahead, alternative 1 is what comes - // afterwards. - RegExpNode* node = alternatives_->at(1).node(); - RegExpNode* replacement = node->FilterASCII(depth - 1); - if (replacement == NULL) return set_replacement(NULL); - alternatives_->at(1).set_node(replacement); - - RegExpNode* neg_node = alternatives_->at(0).node(); - RegExpNode* neg_replacement = neg_node->FilterASCII(depth - 1); - // If the negative lookahead is always going to fail then - // we don't need to check it. - if (neg_replacement == NULL) return set_replacement(replacement); - alternatives_->at(0).set_node(neg_replacement); - return set_replacement(this); -} - - void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, RegExpCompiler* compiler, int characters_filled_in, @@ -2793,24 +2165,6 @@ void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, } -void LoopChoiceNode::FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - if (body_can_be_zero_length_ || - recursion_depth > RegExpCompiler::kMaxRecursion || - budget <= 0) { - bm->SetRest(offset); - SaveBMInfo(bm, not_at_start, offset); - return; - } - ChoiceNode::FillInBMInfo( - offset, recursion_depth + 1, budget - 1, bm, not_at_start); - SaveBMInfo(bm, not_at_start, offset); -} - - void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, RegExpCompiler* compiler, int characters_filled_in, @@ -2895,83 +2249,110 @@ static void EmitHat(RegExpCompiler* compiler, } -// Emit the code to handle \b and \B (word-boundary or non-word-boundary). -void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { +// Emit the code to handle \b and \B (word-boundary or non-word-boundary) +// when we know whether the next character must be a word character or not. +static void EmitHalfBoundaryCheck(AssertionNode::AssertionNodeType type, + RegExpCompiler* compiler, + RegExpNode* on_success, + Trace* trace) { RegExpMacroAssembler* assembler = compiler->macro_assembler(); - Trace::TriBool next_is_word_character = Trace::UNKNOWN; - bool not_at_start = (trace->at_start() == Trace::FALSE); - BoyerMooreLookahead* lookahead = bm_info(not_at_start); - if (lookahead == NULL) { - int eats_at_least = - Min(kMaxLookaheadForBoyerMoore, - EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); - if (eats_at_least >= 1) { - BoyerMooreLookahead* bm = - new BoyerMooreLookahead(eats_at_least, compiler); - FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); - if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; - if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; - } - } else { - if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; - if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; - } - bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); - if (next_is_word_character == Trace::UNKNOWN) { - Label before_non_word; - Label before_word; - if (trace->characters_preloaded() != 1) { - assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word); - } - // Fall through on non-word. - EmitWordCheck(assembler, &before_word, &before_non_word, false); - // Next character is not a word character. - assembler->Bind(&before_non_word); - Label ok; - BacktrackIfPrevious(compiler, trace, at_boundary ? kIsNonWord : kIsWord); - assembler->GoTo(&ok); - - assembler->Bind(&before_word); - BacktrackIfPrevious(compiler, trace, at_boundary ? kIsWord : kIsNonWord); - assembler->Bind(&ok); - } else if (next_is_word_character == Trace::TRUE) { - BacktrackIfPrevious(compiler, trace, at_boundary ? kIsWord : kIsNonWord); - } else { - ASSERT(next_is_word_character == Trace::FALSE); - BacktrackIfPrevious(compiler, trace, at_boundary ? kIsNonWord : kIsWord); + Label done; + + Trace new_trace(*trace); + + bool expect_word_character = (type == AssertionNode::AFTER_WORD_CHARACTER); + Label* on_word = expect_word_character ? &done : new_trace.backtrack(); + Label* on_non_word = expect_word_character ? new_trace.backtrack() : &done; + + // Check whether previous character was a word character. + switch (trace->at_start()) { + case Trace::TRUE: + if (expect_word_character) { + assembler->GoTo(on_non_word); + } + break; + case Trace::UNKNOWN: + ASSERT_EQ(0, trace->cp_offset()); + assembler->CheckAtStart(on_non_word); + // Fall through. + case Trace::FALSE: + int prev_char_offset = trace->cp_offset() - 1; + assembler->LoadCurrentCharacter(prev_char_offset, NULL, false, 1); + EmitWordCheck(assembler, on_word, on_non_word, expect_word_character); + // We may or may not have loaded the previous character. + new_trace.InvalidateCurrentCharacter(); } + + assembler->Bind(&done); + + on_success->Emit(compiler, &new_trace); } -void AssertionNode::BacktrackIfPrevious( - RegExpCompiler* compiler, - Trace* trace, - AssertionNode::IfPrevious backtrack_if_previous) { +// Emit the code to handle \b and \B (word-boundary or non-word-boundary). +static void EmitBoundaryCheck(AssertionNode::AssertionNodeType type, + RegExpCompiler* compiler, + RegExpNode* on_success, + Trace* trace) { RegExpMacroAssembler* assembler = compiler->macro_assembler(); + Label before_non_word; + Label before_word; + if (trace->characters_preloaded() != 1) { + assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word); + } + // Fall through on non-word. + EmitWordCheck(assembler, &before_word, &before_non_word, false); + + // We will be loading the previous character into the current character + // register. Trace new_trace(*trace); new_trace.InvalidateCurrentCharacter(); - Label fall_through, dummy; + Label ok; + Label* boundary; + Label* not_boundary; + if (type == AssertionNode::AT_BOUNDARY) { + boundary = &ok; + not_boundary = new_trace.backtrack(); + } else { + not_boundary = &ok; + boundary = new_trace.backtrack(); + } - Label* non_word = backtrack_if_previous == kIsNonWord ? - new_trace.backtrack() : - &fall_through; - Label* word = backtrack_if_previous == kIsNonWord ? - &fall_through : - new_trace.backtrack(); + // Next character is not a word character. + assembler->Bind(&before_non_word); + if (new_trace.cp_offset() == 0) { + // The start of input counts as a non-word character, so the question is + // decided if we are at the start. + assembler->CheckAtStart(not_boundary); + } + // We already checked that we are not at the start of input so it must be + // OK to load the previous character. + assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, + &ok, // Unused dummy label in this call. + false); + // Fall through on non-word. + EmitWordCheck(assembler, boundary, not_boundary, false); + assembler->GoTo(not_boundary); + // Next character is a word character. + assembler->Bind(&before_word); if (new_trace.cp_offset() == 0) { // The start of input counts as a non-word character, so the question is // decided if we are at the start. - assembler->CheckAtStart(non_word); + assembler->CheckAtStart(boundary); } // We already checked that we are not at the start of input so it must be // OK to load the previous character. - assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, &dummy, false); - EmitWordCheck(assembler, word, non_word, backtrack_if_previous == kIsNonWord); + assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, + &ok, // Unused dummy label in this call. + false); + bool fall_through_on_word = (type == AssertionNode::AT_NON_BOUNDARY); + EmitWordCheck(assembler, not_boundary, boundary, fall_through_on_word); - assembler->Bind(&fall_through); - on_success()->Emit(compiler, &new_trace); + assembler->Bind(&ok); + + on_success->Emit(compiler, &new_trace); } @@ -3019,9 +2400,13 @@ void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) { return; case AT_BOUNDARY: case AT_NON_BOUNDARY: { - EmitBoundaryCheck(compiler, trace); + EmitBoundaryCheck(type_, compiler, on_success(), trace); return; } + case AFTER_WORD_CHARACTER: + case AFTER_NONWORD_CHARACTER: { + EmitHalfBoundaryCheck(type_, compiler, on_success(), trace); + } } on_success()->Emit(compiler, trace); } @@ -3276,30 +2661,6 @@ int TextNode::GreedyLoopTextLength() { } -RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( - RegExpCompiler* compiler) { - if (elms_->length() != 1) return NULL; - TextElement elm = elms_->at(0); - if (elm.type != TextElement::CHAR_CLASS) return NULL; - RegExpCharacterClass* node = elm.data.u_char_class; - ZoneList<CharacterRange>* ranges = node->ranges(); - if (!CharacterRange::IsCanonical(ranges)) { - CharacterRange::Canonicalize(ranges); - } - if (node->is_negated()) { - return ranges->length() == 0 ? on_success() : NULL; - } - if (ranges->length() != 1) return NULL; - uint32_t max_char; - if (compiler->ascii()) { - max_char = String::kMaxAsciiCharCode; - } else { - max_char = String::kMaxUtf16CodeUnit; - } - return ranges->at(0).IsEverything(max_char) ? on_success() : NULL; -} - - // Finds the fixed match length of a sequence of nodes that goes from // this alternative and back to this choice node. If there are variable // length nodes or other complications in the way then return a sentinel @@ -3364,8 +2725,8 @@ void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler, - int eats_at_least) { - int preload_characters = Min(4, eats_at_least); + bool not_at_start) { + int preload_characters = EatsAtLeast(4, 0, not_at_start); if (compiler->macro_assembler()->CanReadUnaligned()) { bool ascii = compiler->ascii(); if (ascii) { @@ -3431,250 +2792,6 @@ class AlternativeGenerationList { }; -// The '2' variant is has inclusive from and exclusive to. -static const int kSpaceRanges[] = { '\t', '\r' + 1, ' ', ' ' + 1, 0x00A0, - 0x00A1, 0x1680, 0x1681, 0x180E, 0x180F, 0x2000, 0x200B, 0x2028, 0x202A, - 0x202F, 0x2030, 0x205F, 0x2060, 0x3000, 0x3001, 0xFEFF, 0xFF00, 0x10000 }; -static const int kSpaceRangeCount = ARRAY_SIZE(kSpaceRanges); - -static const int kWordRanges[] = { - '0', '9' + 1, 'A', 'Z' + 1, '_', '_' + 1, 'a', 'z' + 1, 0x10000 }; -static const int kWordRangeCount = ARRAY_SIZE(kWordRanges); -static const int kDigitRanges[] = { '0', '9' + 1, 0x10000 }; -static const int kDigitRangeCount = ARRAY_SIZE(kDigitRanges); -static const int kSurrogateRanges[] = { 0xd800, 0xe000, 0x10000 }; -static const int kSurrogateRangeCount = ARRAY_SIZE(kSurrogateRanges); -static const int kLineTerminatorRanges[] = { 0x000A, 0x000B, 0x000D, 0x000E, - 0x2028, 0x202A, 0x10000 }; -static const int kLineTerminatorRangeCount = ARRAY_SIZE(kLineTerminatorRanges); - - -void BoyerMoorePositionInfo::Set(int character) { - SetInterval(Interval(character, character)); -} - - -void BoyerMoorePositionInfo::SetInterval(const Interval& interval) { - s_ = AddRange(s_, kSpaceRanges, kSpaceRangeCount, interval); - w_ = AddRange(w_, kWordRanges, kWordRangeCount, interval); - d_ = AddRange(d_, kDigitRanges, kDigitRangeCount, interval); - surrogate_ = - AddRange(surrogate_, kSurrogateRanges, kSurrogateRangeCount, interval); - if (interval.to() - interval.from() >= kMapSize - 1) { - if (map_count_ != kMapSize) { - map_count_ = kMapSize; - for (int i = 0; i < kMapSize; i++) map_->at(i) = true; - } - return; - } - for (int i = interval.from(); i <= interval.to(); i++) { - int mod_character = (i & kMask); - if (!map_->at(mod_character)) { - map_count_++; - map_->at(mod_character) = true; - } - if (map_count_ == kMapSize) return; - } -} - - -void BoyerMoorePositionInfo::SetAll() { - s_ = w_ = d_ = kLatticeUnknown; - if (map_count_ != kMapSize) { - map_count_ = kMapSize; - for (int i = 0; i < kMapSize; i++) map_->at(i) = true; - } -} - - -BoyerMooreLookahead::BoyerMooreLookahead( - int length, RegExpCompiler* compiler) - : length_(length), - compiler_(compiler) { - if (compiler->ascii()) { - max_char_ = String::kMaxAsciiCharCode; - } else { - max_char_ = String::kMaxUtf16CodeUnit; - } - bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length); - for (int i = 0; i < length; i++) { - bitmaps_->Add(new BoyerMoorePositionInfo()); - } -} - - -// Find the longest range of lookahead that has the fewest number of different -// characters that can occur at a given position. Since we are optimizing two -// different parameters at once this is a tradeoff. -bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) { - int biggest_points = 0; - // If more than 32 characters out of 128 can occur it is unlikely that we can - // be lucky enough to step forwards much of the time. - const int kMaxMax = 32; - for (int max_number_of_chars = 4; - max_number_of_chars < kMaxMax; - max_number_of_chars *= 2) { - biggest_points = - FindBestInterval(max_number_of_chars, biggest_points, from, to); - } - if (biggest_points == 0) return false; - return true; -} - - -// Find the highest-points range between 0 and length_ where the character -// information is not too vague. 'Too vague' means that there are more than -// max_number_of_chars that can occur at this position. Calculates the number -// of points as the product of width-of-the-range and -// probability-of-finding-one-of-the-characters, where the probability is -// calculated using the frequency distribution of the sample subject string. -int BoyerMooreLookahead::FindBestInterval( - int max_number_of_chars, int old_biggest_points, int* from, int* to) { - int biggest_points = old_biggest_points; - static const int kSize = RegExpMacroAssembler::kTableSize; - for (int i = 0; i < length_; ) { - while (i < length_ && Count(i) > max_number_of_chars) i++; - if (i == length_) break; - int remembered_from = i; - bool union_map[kSize]; - for (int j = 0; j < kSize; j++) union_map[j] = false; - while (i < length_ && Count(i) <= max_number_of_chars) { - BoyerMoorePositionInfo* map = bitmaps_->at(i); - for (int j = 0; j < kSize; j++) union_map[j] |= map->at(j); - i++; - } - int frequency = 0; - for (int j = 0; j < kSize; j++) { - if (union_map[j]) { - // Add 1 to the frequency to give a small per-character boost for - // the cases where our sampling is not good enough and many - // characters have a frequency of zero. This means the frequency - // can theoretically be up to 2*kSize though we treat it mostly as - // a fraction of kSize. - frequency += compiler_->frequency_collator()->Frequency(j) + 1; - } - } - // We use the probability of skipping times the distance we are skipping to - // judge the effectiveness of this. Actually we have a cut-off: By - // dividing by 2 we switch off the skipping if the probability of skipping - // is less than 50%. This is because the multibyte mask-and-compare - // skipping in quickcheck is more likely to do well on this case. - bool in_quickcheck_range = ((i - remembered_from < 4) || - (compiler_->ascii() ? remembered_from <= 4 : remembered_from <= 2)); - // Called 'probability' but it is only a rough estimate and can actually - // be outside the 0-kSize range. - int probability = (in_quickcheck_range ? kSize / 2 : kSize) - frequency; - int points = (i - remembered_from) * probability; - if (points > biggest_points) { - *from = remembered_from; - *to = i - 1; - biggest_points = points; - } - } - return biggest_points; -} - - -// Take all the characters that will not prevent a successful match if they -// occur in the subject string in the range between min_lookahead and -// max_lookahead (inclusive) measured from the current position. If the -// character at max_lookahead offset is not one of these characters, then we -// can safely skip forwards by the number of characters in the range. -int BoyerMooreLookahead::GetSkipTable(int min_lookahead, - int max_lookahead, - Handle<ByteArray> boolean_skip_table) { - const int kSize = RegExpMacroAssembler::kTableSize; - - const int kSkipArrayEntry = 0; - const int kDontSkipArrayEntry = 1; - - for (int i = 0; i < kSize; i++) { - boolean_skip_table->set(i, kSkipArrayEntry); - } - int skip = max_lookahead + 1 - min_lookahead; - - for (int i = max_lookahead; i >= min_lookahead; i--) { - BoyerMoorePositionInfo* map = bitmaps_->at(i); - for (int j = 0; j < kSize; j++) { - if (map->at(j)) { - boolean_skip_table->set(j, kDontSkipArrayEntry); - } - } - } - - return skip; -} - - -// See comment above on the implementation of GetSkipTable. -bool BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm) { - const int kSize = RegExpMacroAssembler::kTableSize; - - int min_lookahead = 0; - int max_lookahead = 0; - - if (!FindWorthwhileInterval(&min_lookahead, &max_lookahead)) return false; - - bool found_single_character = false; - int single_character = 0; - for (int i = max_lookahead; i >= min_lookahead; i--) { - BoyerMoorePositionInfo* map = bitmaps_->at(i); - if (map->map_count() > 1 || - (found_single_character && map->map_count() != 0)) { - found_single_character = false; - break; - } - for (int j = 0; j < kSize; j++) { - if (map->at(j)) { - found_single_character = true; - single_character = j; - break; - } - } - } - - int lookahead_width = max_lookahead + 1 - min_lookahead; - - if (found_single_character && lookahead_width == 1 && max_lookahead < 3) { - // The mask-compare can probably handle this better. - return false; - } - - if (found_single_character) { - Label cont, again; - masm->Bind(&again); - masm->LoadCurrentCharacter(max_lookahead, &cont, true); - if (max_char_ > kSize) { - masm->CheckCharacterAfterAnd(single_character, - RegExpMacroAssembler::kTableMask, - &cont); - } else { - masm->CheckCharacter(single_character, &cont); - } - masm->AdvanceCurrentPosition(lookahead_width); - masm->GoTo(&again); - masm->Bind(&cont); - return true; - } - - Handle<ByteArray> boolean_skip_table = - FACTORY->NewByteArray(kSize, TENURED); - int skip_distance = GetSkipTable( - min_lookahead, max_lookahead, boolean_skip_table); - ASSERT(skip_distance != 0); - - Label cont, again; - masm->Bind(&again); - masm->LoadCurrentCharacter(max_lookahead, &cont, true); - masm->CheckBitInTable(boolean_skip_table, &cont); - masm->AdvanceCurrentPosition(skip_distance); - masm->GoTo(&again); - masm->Bind(&cont); - - return true; -} - - /* Code generation for choice nodes. * * We generate quick checks that do a mask and compare to eliminate a @@ -3753,6 +2870,7 @@ bool BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm) { * \______________/ */ + void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); int choice_count = alternatives_->length(); @@ -3817,52 +2935,10 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) { int first_normal_choice = greedy_loop ? 1 : 0; - bool not_at_start = current_trace->at_start() == Trace::FALSE; - const int kEatsAtLeastNotYetInitialized = -1; - int eats_at_least = kEatsAtLeastNotYetInitialized; - - bool skip_was_emitted = false; - - if (!greedy_loop && choice_count == 2) { - GuardedAlternative alt1 = alternatives_->at(1); - if (alt1.guards() == NULL || alt1.guards()->length() == 0) { - RegExpNode* eats_anything_node = alt1.node(); - if (eats_anything_node->GetSuccessorOfOmnivorousTextNode(compiler) == - this) { - // At this point we know that we are at a non-greedy loop that will eat - // any character one at a time. Any non-anchored regexp has such a - // loop prepended to it in order to find where it starts. We look for - // a pattern of the form ...abc... where we can look 6 characters ahead - // and step forwards 3 if the character is not one of abc. Abc need - // not be atoms, they can be any reasonably limited character class or - // small alternation. - ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. - BoyerMooreLookahead* lookahead = bm_info(not_at_start); - if (lookahead == NULL) { - eats_at_least = - Min(kMaxLookaheadForBoyerMoore, - EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); - if (eats_at_least >= 1) { - BoyerMooreLookahead* bm = - new BoyerMooreLookahead(eats_at_least, compiler); - GuardedAlternative alt0 = alternatives_->at(0); - alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); - skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); - } - } else { - skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); - } - } - } - } - - if (eats_at_least == kEatsAtLeastNotYetInitialized) { - // Save some time by looking at most one machine word ahead. - eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start); - } - int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); - - bool preload_is_current = !skip_was_emitted && + int preload_characters = + CalculatePreloadCharacters(compiler, + current_trace->at_start() == Trace::FALSE); + bool preload_is_current = (current_trace->characters_preloaded() == preload_characters); bool preload_has_checked_bounds = preload_is_current; @@ -4413,6 +3489,12 @@ void DotPrinter::VisitAssertion(AssertionNode* that) { case AssertionNode::AFTER_NEWLINE: stream()->Add("label=\"(?<=\\n)\", shape=septagon"); break; + case AssertionNode::AFTER_WORD_CHARACTER: + stream()->Add("label=\"(?<=\\w)\", shape=septagon"); + break; + case AssertionNode::AFTER_NONWORD_CHARACTER: + stream()->Add("label=\"(?<=\\W)\", shape=septagon"); + break; } stream()->Add("];\n"); PrintAttributes(that); @@ -4517,6 +3599,21 @@ void RegExpEngine::DotPrint(const char* label, // ------------------------------------------------------------------- // Tree to graph conversion +static const uc16 kSpaceRanges[] = { 0x0009, 0x000D, 0x0020, 0x0020, 0x00A0, + 0x00A0, 0x1680, 0x1680, 0x180E, 0x180E, 0x2000, 0x200A, 0x2028, 0x2029, + 0x202F, 0x202F, 0x205F, 0x205F, 0x3000, 0x3000, 0xFEFF, 0xFEFF }; +static const int kSpaceRangeCount = ARRAY_SIZE(kSpaceRanges); + +static const uc16 kWordRanges[] = { '0', '9', 'A', 'Z', '_', '_', 'a', 'z' }; +static const int kWordRangeCount = ARRAY_SIZE(kWordRanges); + +static const uc16 kDigitRanges[] = { '0', '9' }; +static const int kDigitRangeCount = ARRAY_SIZE(kDigitRanges); + +static const uc16 kLineTerminatorRanges[] = { 0x000A, 0x000A, 0x000D, 0x000D, + 0x2028, 0x2029 }; +static const int kLineTerminatorRangeCount = ARRAY_SIZE(kLineTerminatorRanges); + RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, RegExpNode* on_success) { ZoneList<TextElement>* elms = new ZoneList<TextElement>(1); @@ -4530,12 +3627,9 @@ RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler, return new TextNode(elements(), on_success); } - static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges, - const int* special_class, + const uc16* special_class, int length) { - length--; // Remove final 0x10000. - ASSERT(special_class[length] == 0x10000); ASSERT(ranges->length() != 0); ASSERT(length != 0); ASSERT(special_class[0] != 0); @@ -4551,7 +3645,7 @@ static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges, return false; } range = ranges->at((i >> 1) + 1); - if (special_class[i+1] != range.from()) { + if (special_class[i+1] != range.from() - 1) { return false; } } @@ -4563,17 +3657,14 @@ static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges, static bool CompareRanges(ZoneList<CharacterRange>* ranges, - const int* special_class, + const uc16* special_class, int length) { - length--; // Remove final 0x10000. - ASSERT(special_class[length] == 0x10000); if (ranges->length() * 2 != length) { return false; } for (int i = 0; i < length; i += 2) { CharacterRange range = ranges->at(i >> 1); - if (range.from() != special_class[i] || - range.to() != special_class[i + 1] - 1) { + if (range.from() != special_class[i] || range.to() != special_class[i+1]) { return false; } } @@ -4974,31 +4065,27 @@ RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler, } -static void AddClass(const int* elmv, +static void AddClass(const uc16* elmv, int elmc, ZoneList<CharacterRange>* ranges) { - elmc--; - ASSERT(elmv[elmc] == 0x10000); for (int i = 0; i < elmc; i += 2) { - ASSERT(elmv[i] < elmv[i + 1]); - ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1)); + ASSERT(elmv[i] <= elmv[i + 1]); + ranges->Add(CharacterRange(elmv[i], elmv[i + 1])); } } -static void AddClassNegated(const int *elmv, +static void AddClassNegated(const uc16 *elmv, int elmc, ZoneList<CharacterRange>* ranges) { - elmc--; - ASSERT(elmv[elmc] == 0x10000); ASSERT(elmv[0] != 0x0000); ASSERT(elmv[elmc-1] != String::kMaxUtf16CodeUnit); uc16 last = 0x0000; for (int i = 0; i < elmc; i += 2) { ASSERT(last <= elmv[i] - 1); - ASSERT(elmv[i] < elmv[i + 1]); + ASSERT(elmv[i] <= elmv[i + 1]); ranges->Add(CharacterRange(last, elmv[i] - 1)); - last = elmv[i + 1]; + last = elmv[i + 1] + 1; } ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit)); } @@ -5049,8 +4136,8 @@ void CharacterRange::AddClassEscape(uc16 type, } -Vector<const int> CharacterRange::GetWordBounds() { - return Vector<const int>(kWordRanges, kWordRangeCount - 1); +Vector<const uc16> CharacterRange::GetWordBounds() { + return Vector<const uc16>(kWordRanges, kWordRangeCount); } @@ -5082,7 +4169,7 @@ void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) { void CharacterRange::Split(ZoneList<CharacterRange>* base, - Vector<const int> overlay, + Vector<const uc16> overlay, ZoneList<CharacterRange>** included, ZoneList<CharacterRange>** excluded) { ASSERT_EQ(NULL, *included); @@ -5091,7 +4178,7 @@ void CharacterRange::Split(ZoneList<CharacterRange>* base, for (int i = 0; i < base->length(); i++) table.AddRange(base->at(i), CharacterRangeSplitter::kInBase); for (int i = 0; i < overlay.length(); i += 2) { - table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1), + table.AddRange(CharacterRange(overlay[i], overlay[i+1]), CharacterRangeSplitter::kInOverlay); } CharacterRangeSplitter callback(included, excluded); @@ -5139,7 +4226,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges, // as a "singleton block"). unibrow::uchar range[unibrow::Ecma262UnCanonicalize::kMaxWidth]; int pos = bottom; - while (pos <= top) { + while (pos < top) { int length = isolate->jsregexp_canonrange()->get(pos, '\0', range); uc16 block_end; if (length == 0) { @@ -5177,6 +4264,87 @@ bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) { return true; } +SetRelation CharacterRange::WordCharacterRelation( + ZoneList<CharacterRange>* range) { + ASSERT(IsCanonical(range)); + int i = 0; // Word character range index. + int j = 0; // Argument range index. + ASSERT_NE(0, kWordRangeCount); + SetRelation result; + if (range->length() == 0) { + result.SetElementsInSecondSet(); + return result; + } + CharacterRange argument_range = range->at(0); + CharacterRange word_range = CharacterRange(kWordRanges[0], kWordRanges[1]); + while (i < kWordRangeCount && j < range->length()) { + // Check the two ranges for the five cases: + // - no overlap. + // - partial overlap (there are elements in both ranges that isn't + // in the other, and there are also elements that are in both). + // - argument range entirely inside word range. + // - word range entirely inside argument range. + // - ranges are completely equal. + + // First check for no overlap. The earlier range is not in the other set. + if (argument_range.from() > word_range.to()) { + // Ranges are disjoint. The earlier word range contains elements that + // cannot be in the argument set. + result.SetElementsInSecondSet(); + } else if (word_range.from() > argument_range.to()) { + // Ranges are disjoint. The earlier argument range contains elements that + // cannot be in the word set. + result.SetElementsInFirstSet(); + } else if (word_range.from() <= argument_range.from() && + word_range.to() >= argument_range.from()) { + result.SetElementsInBothSets(); + // argument range completely inside word range. + if (word_range.from() < argument_range.from() || + word_range.to() > argument_range.from()) { + result.SetElementsInSecondSet(); + } + } else if (word_range.from() >= argument_range.from() && + word_range.to() <= argument_range.from()) { + result.SetElementsInBothSets(); + result.SetElementsInFirstSet(); + } else { + // There is overlap, and neither is a subrange of the other + result.SetElementsInFirstSet(); + result.SetElementsInSecondSet(); + result.SetElementsInBothSets(); + } + if (result.NonTrivialIntersection()) { + // The result is as (im)precise as we can possibly make it. + return result; + } + // Progress the range(s) with minimal to-character. + uc16 word_to = word_range.to(); + uc16 argument_to = argument_range.to(); + if (argument_to <= word_to) { + j++; + if (j < range->length()) { + argument_range = range->at(j); + } + } + if (word_to <= argument_to) { + i += 2; + if (i < kWordRangeCount) { + word_range = CharacterRange(kWordRanges[i], kWordRanges[i + 1]); + } + } + } + // Check if anything wasn't compared in the loop. + if (i < kWordRangeCount) { + // word range contains something not in argument range. + result.SetElementsInSecondSet(); + } else if (j < range->length()) { + // Argument range contains something not in word range. + result.SetElementsInFirstSet(); + } + + return result; +} + ZoneList<CharacterRange>* CharacterSet::ranges() { if (ranges_ == NULL) { @@ -5309,6 +4477,145 @@ void CharacterRange::Canonicalize(ZoneList<CharacterRange>* character_ranges) { } +// Utility function for CharacterRange::Merge. Adds a range at the end of +// a canonicalized range list, if necessary merging the range with the last +// range of the list. +static void AddRangeToSet(ZoneList<CharacterRange>* set, CharacterRange range) { + if (set == NULL) return; + ASSERT(set->length() == 0 || set->at(set->length() - 1).to() < range.from()); + int n = set->length(); + if (n > 0) { + CharacterRange lastRange = set->at(n - 1); + if (lastRange.to() == range.from() - 1) { + set->at(n - 1) = CharacterRange(lastRange.from(), range.to()); + return; + } + } + set->Add(range); +} + + +static void AddRangeToSelectedSet(int selector, + ZoneList<CharacterRange>* first_set, + ZoneList<CharacterRange>* second_set, + ZoneList<CharacterRange>* intersection_set, + CharacterRange range) { + switch (selector) { + case kInsideFirst: + AddRangeToSet(first_set, range); + break; + case kInsideSecond: + AddRangeToSet(second_set, range); + break; + case kInsideBoth: + AddRangeToSet(intersection_set, range); + break; + } +} + + + +void CharacterRange::Merge(ZoneList<CharacterRange>* first_set, + ZoneList<CharacterRange>* second_set, + ZoneList<CharacterRange>* first_set_only_out, + ZoneList<CharacterRange>* second_set_only_out, + ZoneList<CharacterRange>* both_sets_out) { + // Inputs are canonicalized. + ASSERT(CharacterRange::IsCanonical(first_set)); + ASSERT(CharacterRange::IsCanonical(second_set)); + // Outputs are empty, if applicable. + ASSERT(first_set_only_out == NULL || first_set_only_out->length() == 0); + ASSERT(second_set_only_out == NULL || second_set_only_out->length() == 0); + ASSERT(both_sets_out == NULL || both_sets_out->length() == 0); + + // Merge sets by iterating through the lists in order of lowest "from" value, + // and putting intervals into one of three sets. + + if (first_set->length() == 0) { + second_set_only_out->AddAll(*second_set); + return; + } + if (second_set->length() == 0) { + first_set_only_out->AddAll(*first_set); + return; + } + // Indices into input lists. + int i1 = 0; + int i2 = 0; + // Cache length of input lists. + int n1 = first_set->length(); + int n2 = second_set->length(); + // Current range. May be invalid if state is kInsideNone. + int from = 0; + int to = -1; + // Where current range comes from. + int state = kInsideNone; + + while (i1 < n1 || i2 < n2) { + CharacterRange next_range; + int range_source; + if (i2 == n2 || + (i1 < n1 && first_set->at(i1).from() < second_set->at(i2).from())) { + // Next smallest element is in first set. + next_range = first_set->at(i1++); + range_source = kInsideFirst; + } else { + // Next smallest element is in second set. + next_range = second_set->at(i2++); + range_source = kInsideSecond; + } + if (to < next_range.from()) { + // Ranges disjoint: |current| |next| + AddRangeToSelectedSet(state, + first_set_only_out, + second_set_only_out, + both_sets_out, + CharacterRange(from, to)); + from = next_range.from(); + to = next_range.to(); + state = range_source; + } else { + if (from < next_range.from()) { + AddRangeToSelectedSet(state, + first_set_only_out, + second_set_only_out, + both_sets_out, + CharacterRange(from, next_range.from()-1)); + } + if (to < next_range.to()) { + // Ranges overlap: |current| + // |next| + AddRangeToSelectedSet(state | range_source, + first_set_only_out, + second_set_only_out, + both_sets_out, + CharacterRange(next_range.from(), to)); + from = to + 1; + to = next_range.to(); + state = range_source; + } else { + // Range included: |current| , possibly ending at same character. + // |next| + AddRangeToSelectedSet( + state | range_source, + first_set_only_out, + second_set_only_out, + both_sets_out, + CharacterRange(next_range.from(), next_range.to())); + from = next_range.to() + 1; + // If ranges end at same character, both ranges are consumed completely. + if (next_range.to() == to) state = kInsideNone; + } + } + } + AddRangeToSelectedSet(state, + first_set_only_out, + second_set_only_out, + both_sets_out, + CharacterRange(from, to)); +} + + void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, ZoneList<CharacterRange>* negated_ranges) { ASSERT(CharacterRange::IsCanonical(ranges)); @@ -5332,6 +4639,45 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges, } + +// ------------------------------------------------------------------- +// Interest propagation + + +RegExpNode* RegExpNode::TryGetSibling(NodeInfo* info) { + for (int i = 0; i < siblings_.length(); i++) { + RegExpNode* sibling = siblings_.Get(i); + if (sibling->info()->Matches(info)) + return sibling; + } + return NULL; +} + + +RegExpNode* RegExpNode::EnsureSibling(NodeInfo* info, bool* cloned) { + ASSERT_EQ(false, *cloned); + siblings_.Ensure(this); + RegExpNode* result = TryGetSibling(info); + if (result != NULL) return result; + result = this->Clone(); + NodeInfo* new_info = result->info(); + new_info->ResetCompilationState(); + new_info->AddFromPreceding(info); + AddSibling(result); + *cloned = true; + return result; +} + + +template <class C> +static RegExpNode* PropagateToEndpoint(C* node, NodeInfo* info) { + NodeInfo full_info(*node->info()); + full_info.AddFromPreceding(info); + bool cloned = false; + return RegExpNode::EnsureSibling(node, &full_info, &cloned); +} + + // ------------------------------------------------------------------- // Splay tree @@ -5582,112 +4928,213 @@ void Analysis::VisitBackReference(BackReferenceNode* that) { void Analysis::VisitAssertion(AssertionNode* that) { EnsureAnalyzed(that->on_success()); + AssertionNode::AssertionNodeType type = that->type(); + if (type == AssertionNode::AT_BOUNDARY || + type == AssertionNode::AT_NON_BOUNDARY) { + // Check if the following character is known to be a word character + // or known to not be a word character. + ZoneList<CharacterRange>* following_chars = that->FirstCharacterSet(); + + CharacterRange::Canonicalize(following_chars); + + SetRelation word_relation = + CharacterRange::WordCharacterRelation(following_chars); + if (word_relation.Disjoint()) { + // Includes the case where following_chars is empty (e.g., end-of-input). + // Following character is definitely *not* a word character. + type = (type == AssertionNode::AT_BOUNDARY) ? + AssertionNode::AFTER_WORD_CHARACTER : + AssertionNode::AFTER_NONWORD_CHARACTER; + that->set_type(type); + } else if (word_relation.ContainedIn()) { + // Following character is definitely a word character. + type = (type == AssertionNode::AT_BOUNDARY) ? + AssertionNode::AFTER_NONWORD_CHARACTER : + AssertionNode::AFTER_WORD_CHARACTER; + that->set_type(type); + } + } } -void BackReferenceNode::FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - // Working out the set of characters that a backreference can match is too - // hard, so we just say that any character can match. - bm->SetRest(offset); - SaveBMInfo(bm, not_at_start, offset); +ZoneList<CharacterRange>* RegExpNode::FirstCharacterSet() { + if (first_character_set_ == NULL) { + if (ComputeFirstCharacterSet(kFirstCharBudget) < 0) { + // If we can't find an exact solution within the budget, we + // set the value to the set of every character, i.e., all characters + // are possible. + ZoneList<CharacterRange>* all_set = new ZoneList<CharacterRange>(1); + all_set->Add(CharacterRange::Everything()); + first_character_set_ = all_set; + } + } + return first_character_set_; } -STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize == - RegExpMacroAssembler::kTableSize); +int RegExpNode::ComputeFirstCharacterSet(int budget) { + // Default behavior is to not be able to determine the first character. + return kComputeFirstCharacterSetFail; +} -void ChoiceNode::FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - ZoneList<GuardedAlternative>* alts = alternatives(); - budget = (budget - 1) / alts->length(); - for (int i = 0; i < alts->length(); i++) { - GuardedAlternative& alt = alts->at(i); - if (alt.guards() != NULL && alt.guards()->length() != 0) { - bm->SetRest(offset); // Give up trying to fill in info. - SaveBMInfo(bm, not_at_start, offset); - return; +int LoopChoiceNode::ComputeFirstCharacterSet(int budget) { + budget--; + if (budget >= 0) { + // Find loop min-iteration. It's the value of the guarded choice node + // with a GEQ guard, if any. + int min_repetition = 0; + + for (int i = 0; i <= 1; i++) { + GuardedAlternative alternative = alternatives()->at(i); + ZoneList<Guard*>* guards = alternative.guards(); + if (guards != NULL && guards->length() > 0) { + Guard* guard = guards->at(0); + if (guard->op() == Guard::GEQ) { + min_repetition = guard->value(); + break; + } + } + } + + budget = loop_node()->ComputeFirstCharacterSet(budget); + if (budget >= 0) { + ZoneList<CharacterRange>* character_set = + loop_node()->first_character_set(); + if (body_can_be_zero_length() || min_repetition == 0) { + budget = continue_node()->ComputeFirstCharacterSet(budget); + if (budget < 0) return budget; + ZoneList<CharacterRange>* body_set = + continue_node()->first_character_set(); + ZoneList<CharacterRange>* union_set = + new ZoneList<CharacterRange>(Max(character_set->length(), + body_set->length())); + CharacterRange::Merge(character_set, + body_set, + union_set, + union_set, + union_set); + character_set = union_set; + } + set_first_character_set(character_set); } - alt.node()->FillInBMInfo( - offset, recursion_depth + 1, budget, bm, not_at_start); } - SaveBMInfo(bm, not_at_start, offset); + return budget; } -void TextNode::FillInBMInfo(int initial_offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - if (initial_offset >= bm->length()) return; - int offset = initial_offset; - int max_char = bm->max_char(); - for (int i = 0; i < elements()->length(); i++) { - if (offset >= bm->length()) { - if (initial_offset == 0) set_bm_info(not_at_start, bm); - return; +int NegativeLookaheadChoiceNode::ComputeFirstCharacterSet(int budget) { + budget--; + if (budget >= 0) { + GuardedAlternative successor = this->alternatives()->at(1); + RegExpNode* successor_node = successor.node(); + budget = successor_node->ComputeFirstCharacterSet(budget); + if (budget >= 0) { + set_first_character_set(successor_node->first_character_set()); } - TextElement text = elements()->at(i); - if (text.type == TextElement::ATOM) { - RegExpAtom* atom = text.data.u_atom; - for (int j = 0; j < atom->length(); j++, offset++) { - if (offset >= bm->length()) { - if (initial_offset == 0) set_bm_info(not_at_start, bm); - return; - } - uc16 character = atom->data()[j]; - if (bm->compiler()->ignore_case()) { - unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; - int length = GetCaseIndependentLetters( - ISOLATE, - character, - bm->max_char() == String::kMaxAsciiCharCode, - chars); - for (int j = 0; j < length; j++) { - bm->Set(offset, chars[j]); - } - } else { - if (character <= max_char) bm->Set(offset, character); + } + return budget; +} + + +// The first character set of an EndNode is unknowable. Just use the +// default implementation that fails and returns all characters as possible. + + +int AssertionNode::ComputeFirstCharacterSet(int budget) { + budget -= 1; + if (budget >= 0) { + switch (type_) { + case AT_END: { + set_first_character_set(new ZoneList<CharacterRange>(0)); + break; + } + case AT_START: + case AT_BOUNDARY: + case AT_NON_BOUNDARY: + case AFTER_NEWLINE: + case AFTER_NONWORD_CHARACTER: + case AFTER_WORD_CHARACTER: { + ASSERT_NOT_NULL(on_success()); + budget = on_success()->ComputeFirstCharacterSet(budget); + if (budget >= 0) { + set_first_character_set(on_success()->first_character_set()); } + break; } + } + } + return budget; +} + + +int ActionNode::ComputeFirstCharacterSet(int budget) { + if (type_ == POSITIVE_SUBMATCH_SUCCESS) return kComputeFirstCharacterSetFail; + budget--; + if (budget >= 0) { + ASSERT_NOT_NULL(on_success()); + budget = on_success()->ComputeFirstCharacterSet(budget); + if (budget >= 0) { + set_first_character_set(on_success()->first_character_set()); + } + } + return budget; +} + + +int BackReferenceNode::ComputeFirstCharacterSet(int budget) { + // We don't know anything about the first character of a backreference + // at this point. + // The potential first characters are the first characters of the capture, + // and the first characters of the on_success node, depending on whether the + // capture can be empty and whether it is known to be participating or known + // not to be. + return kComputeFirstCharacterSetFail; +} + + +int TextNode::ComputeFirstCharacterSet(int budget) { + budget--; + if (budget >= 0) { + ASSERT_NE(0, elements()->length()); + TextElement text = elements()->at(0); + if (text.type == TextElement::ATOM) { + RegExpAtom* atom = text.data.u_atom; + ASSERT_NE(0, atom->length()); + uc16 first_char = atom->data()[0]; + ZoneList<CharacterRange>* range = new ZoneList<CharacterRange>(1); + range->Add(CharacterRange(first_char, first_char)); + set_first_character_set(range); } else { ASSERT(text.type == TextElement::CHAR_CLASS); RegExpCharacterClass* char_class = text.data.u_char_class; ZoneList<CharacterRange>* ranges = char_class->ranges(); + // TODO(lrn): Canonicalize ranges when they are created + // instead of waiting until now. + CharacterRange::Canonicalize(ranges); if (char_class->is_negated()) { - bm->SetAll(offset); - } else { - for (int k = 0; k < ranges->length(); k++) { - CharacterRange& range = ranges->at(k); - if (range.from() > max_char) continue; - int to = Min(max_char, static_cast<int>(range.to())); - bm->SetInterval(offset, Interval(range.from(), to)); + int length = ranges->length(); + int new_length = length + 1; + if (length > 0) { + if (ranges->at(0).from() == 0) new_length--; + if (ranges->at(length - 1).to() == String::kMaxUtf16CodeUnit) { + new_length--; + } } + ZoneList<CharacterRange>* negated_ranges = + new ZoneList<CharacterRange>(new_length); + CharacterRange::Negate(ranges, negated_ranges); + set_first_character_set(negated_ranges); + } else { + set_first_character_set(ranges); } - offset++; } } - if (offset >= bm->length()) { - if (initial_offset == 0) set_bm_info(not_at_start, bm); - return; - } - on_success()->FillInBMInfo(offset, - recursion_depth + 1, - budget - 1, - bm, - true); // Not at start after a text node. - if (initial_offset == 0) set_bm_info(not_at_start, bm); + return budget; } + // ------------------------------------------------------------------- // Dispatch table construction @@ -5803,30 +5250,15 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) { } -RegExpEngine::CompilationResult RegExpEngine::Compile( - RegExpCompileData* data, - bool ignore_case, - bool is_multiline, - Handle<String> pattern, - Handle<String> sample_subject, - bool is_ascii) { +RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data, + bool ignore_case, + bool is_multiline, + Handle<String> pattern, + bool is_ascii) { if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { return IrregexpRegExpTooBig(); } RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); - - // Sample some characters from the middle of the string. - static const int kSampleSize = 128; - - FlattenString(sample_subject); - int chars_sampled = 0; - int half_way = (sample_subject->length() - kSampleSize) / 2; - for (int i = Max(0, half_way); - i < sample_subject->length() && chars_sampled < kSampleSize; - i++, chars_sampled++) { - compiler.frequency_collator()->CountCharacter(sample_subject->Get(i)); - } - // Wrap the body of the regexp in capture #0. RegExpNode* captured_body = RegExpCapture::ToNode(data->tree, 0, @@ -5860,14 +5292,6 @@ RegExpEngine::CompilationResult RegExpEngine::Compile( node = loop_node; } } - if (is_ascii) { - node = node->FilterASCII(RegExpCompiler::kMaxRecursion); - // Do it again to propagate the new nodes to places where they were not - // put because they had not been calculated yet. - if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion); - } - - if (node == NULL) node = new EndNode(EndNode::BACKTRACK); data->node = node; Analysis analysis(ignore_case, is_ascii); analysis.EnsureAnalyzed(node); diff --git a/deps/v8/src/jsregexp.h b/deps/v8/src/jsregexp.h index 6b16dd34db..8875de9eb2 100644 --- a/deps/v8/src/jsregexp.h +++ b/deps/v8/src/jsregexp.h @@ -40,7 +40,6 @@ class RegExpCompiler; class RegExpMacroAssembler; class RegExpNode; class RegExpTree; -class BoyerMooreLookahead; class RegExpImpl { public: @@ -191,10 +190,8 @@ class RegExpImpl { static String* last_ascii_string_; static String* two_byte_cached_string_; - static bool CompileIrregexp( - Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); - static inline bool EnsureCompiledIrregexp( - Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); + static bool CompileIrregexp(Handle<JSRegExp> re, bool is_ascii); + static inline bool EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii); // Set the subject cache. The previous string buffer is not deleted, so the @@ -225,8 +222,48 @@ enum ElementInSetsRelation { }; -// Represents code units in the range from from_ to to_, both ends are -// inclusive. +// Represents the relation of two sets. +// Sets can be either disjoint, partially or fully overlapping, or equal. +class SetRelation BASE_EMBEDDED { + public: + // Relation is represented by a bit saying whether there are elements in + // one set that is not in the other, and a bit saying that there are elements + // that are in both sets. + + // Location of an element. Corresponds to the internal areas of + // a Venn diagram. + enum { + kInFirst = 1 << kInsideFirst, + kInSecond = 1 << kInsideSecond, + kInBoth = 1 << kInsideBoth + }; + SetRelation() : bits_(0) {} + ~SetRelation() {} + // Add the existence of objects in a particular + void SetElementsInFirstSet() { bits_ |= kInFirst; } + void SetElementsInSecondSet() { bits_ |= kInSecond; } + void SetElementsInBothSets() { bits_ |= kInBoth; } + // Check the currently known relation of the sets (common functions only, + // for other combinations, use value() to get the bits and check them + // manually). + // Sets are completely disjoint. + bool Disjoint() { return (bits_ & kInBoth) == 0; } + // Sets are equal. + bool Equals() { return (bits_ & (kInFirst | kInSecond)) == 0; } + // First set contains second. + bool Contains() { return (bits_ & kInSecond) == 0; } + // Second set contains first. + bool ContainedIn() { return (bits_ & kInFirst) == 0; } + bool NonTrivialIntersection() { + return (bits_ == (kInFirst | kInSecond | kInBoth)); + } + int value() { return bits_; } + + private: + int bits_; +}; + + class CharacterRange { public: CharacterRange() : from_(0), to_(0) { } @@ -234,7 +271,7 @@ class CharacterRange { CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { } static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges); - static Vector<const int> GetWordBounds(); + static Vector<const uc16> GetWordBounds(); static inline CharacterRange Singleton(uc16 value) { return CharacterRange(value, value); } @@ -255,7 +292,7 @@ class CharacterRange { bool IsSingleton() { return (from_ == to_); } void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_ascii); static void Split(ZoneList<CharacterRange>* base, - Vector<const int> overlay, + Vector<const uc16> overlay, ZoneList<CharacterRange>** included, ZoneList<CharacterRange>** excluded); // Whether a range list is in canonical form: Ranges ordered by from value, @@ -266,6 +303,28 @@ class CharacterRange { // adjacent ranges are merged. The resulting list may be shorter than the // original, but cannot be longer. static void Canonicalize(ZoneList<CharacterRange>* ranges); + // Check how the set of characters defined by a CharacterRange list relates + // to the set of word characters. List must be in canonical form. + static SetRelation WordCharacterRelation(ZoneList<CharacterRange>* ranges); + // Takes two character range lists (representing character sets) in canonical + // form and merges them. + // The characters that are only covered by the first set are added to + // first_set_only_out. the characters that are only in the second set are + // added to second_set_only_out, and the characters that are in both are + // added to both_sets_out. + // The pointers to first_set_only_out, second_set_only_out and both_sets_out + // should be to empty lists, but they need not be distinct, and may be NULL. + // If NULL, the characters are dropped, and if two arguments are the same + // pointer, the result is the union of the two sets that would be created + // if the pointers had been distinct. + // This way, the Merge function can compute all the usual set operations: + // union (all three out-sets are equal), intersection (only both_sets_out is + // non-NULL), and set difference (only first_set is non-NULL). + static void Merge(ZoneList<CharacterRange>* first_set, + ZoneList<CharacterRange>* second_set, + ZoneList<CharacterRange>* first_set_only_out, + ZoneList<CharacterRange>* second_set_only_out, + ZoneList<CharacterRange>* both_sets_out); // Negate the contents of a character range in canonical form. static void Negate(ZoneList<CharacterRange>* src, ZoneList<CharacterRange>* dst); @@ -416,8 +475,7 @@ struct NodeInfo { follows_newline_interest(false), follows_start_interest(false), at_end(false), - visited(false), - replacement_calculated(false) { } + visited(false) { } // Returns true if the interests and assumptions of this node // matches the given one. @@ -467,7 +525,25 @@ struct NodeInfo { bool at_end: 1; bool visited: 1; - bool replacement_calculated: 1; +}; + + +class SiblingList { + public: + SiblingList() : list_(NULL) { } + int length() { + return list_ == NULL ? 0 : list_->length(); + } + void Ensure(RegExpNode* parent) { + if (list_ == NULL) { + list_ = new ZoneList<RegExpNode*>(2); + list_->Add(parent); + } + } + void Add(RegExpNode* node) { list_->Add(node); } + RegExpNode* Get(int index) { return list_->at(index); } + private: + ZoneList<RegExpNode*>* list_; }; @@ -523,14 +599,9 @@ class QuickCheckDetails { }; -extern int kUninitializedRegExpNodePlaceHolder; - - class RegExpNode: public ZoneObject { public: - RegExpNode() : replacement_(NULL), trace_count_(0) { - bm_info_[0] = bm_info_[1] = NULL; - } + RegExpNode() : first_character_set_(NULL), trace_count_(0) { } virtual ~RegExpNode(); virtual void Accept(NodeVisitor* visitor) = 0; // Generates a goto to this node or actually generates the code at this point. @@ -564,50 +635,6 @@ class RegExpNode: public ZoneObject { bool not_at_start) = 0; static const int kNodeIsTooComplexForGreedyLoops = -1; virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } - // Only returns the successor for a text node of length 1 that matches any - // character and that has no guards on it. - virtual RegExpNode* GetSuccessorOfOmnivorousTextNode( - RegExpCompiler* compiler) { - return NULL; - } - - // Collects information on the possible code units (mod 128) that can match if - // we look forward. This is used for a Boyer-Moore-like string searching - // implementation. TODO(erikcorry): This should share more code with - // EatsAtLeast, GetQuickCheckDetails. The budget argument is used to limit - // the number of nodes we are willing to look at in order to create this data. - static const int kFillInBMBudget = 200; - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - UNREACHABLE(); - } - - // If we know that the input is ASCII then there are some nodes that can - // never match. This method returns a node that can be substituted for - // itself, or NULL if the node can never match. - virtual RegExpNode* FilterASCII(int depth) { return this; } - // Helper for FilterASCII. - RegExpNode* replacement() { - ASSERT(info()->replacement_calculated); - return replacement_; - } - RegExpNode* set_replacement(RegExpNode* replacement) { - info()->replacement_calculated = true; - replacement_ = replacement; - return replacement; // For convenience. - } - - // We want to avoid recalculating the lookahead info, so we store it on the - // node. Only info that is for this node is stored. We can tell that the - // info is for this node when offset == 0, so the information is calculated - // relative to this node. - void SaveBMInfo(BoyerMooreLookahead* bm, bool not_at_start, int offset) { - if (offset == 0) set_bm_info(not_at_start, bm); - } - Label* label() { return &label_; } // If non-generic code is generated for a node (i.e. the node is not at the // start of the trace) then it cannot be reused. This variable sets a limit @@ -618,31 +645,72 @@ class RegExpNode: public ZoneObject { NodeInfo* info() { return &info_; } - BoyerMooreLookahead* bm_info(bool not_at_start) { - return bm_info_[not_at_start ? 1 : 0]; + void AddSibling(RegExpNode* node) { siblings_.Add(node); } + + // Static version of EnsureSibling that expresses the fact that the + // result has the same type as the input. + template <class C> + static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) { + return static_cast<C*>(node->EnsureSibling(info, cloned)); + } + + SiblingList* siblings() { return &siblings_; } + void set_siblings(SiblingList* other) { siblings_ = *other; } + + // Return the set of possible next characters recognized by the regexp + // (or a safe subset, potentially the set of all characters). + ZoneList<CharacterRange>* FirstCharacterSet(); + + // Compute (if possible within the budget of traversed nodes) the + // possible first characters of the input matched by this node and + // its continuation. Returns the remaining budget after the computation. + // If the budget is spent, the result is negative, and the cached + // first_character_set_ value isn't set. + virtual int ComputeFirstCharacterSet(int budget); + + // Get and set the cached first character set value. + ZoneList<CharacterRange>* first_character_set() { + return first_character_set_; + } + void set_first_character_set(ZoneList<CharacterRange>* character_set) { + first_character_set_ = character_set; } protected: enum LimitResult { DONE, CONTINUE }; - RegExpNode* replacement_; + static const int kComputeFirstCharacterSetFail = -1; LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); - void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { - bm_info_[not_at_start ? 1 : 0] = bm; - } + // Returns a sibling of this node whose interests and assumptions + // match the ones in the given node info. If no sibling exists NULL + // is returned. + RegExpNode* TryGetSibling(NodeInfo* info); + + // Returns a sibling of this node whose interests match the ones in + // the given node info. The info must not contain any assertions. + // If no node exists a new one will be created by cloning the current + // node. The result will always be an instance of the same concrete + // class as this node. + RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned); + + // Returns a clone of this node initialized using the copy constructor + // of its concrete class. Note that the node may have to be pre- + // processed before it is on a usable state. + virtual RegExpNode* Clone() = 0; private: static const int kFirstCharBudget = 10; Label label_; NodeInfo info_; + SiblingList siblings_; + ZoneList<CharacterRange>* first_character_set_; // This variable keeps track of how many times code has been generated for // this node (in different traces). We don't keep track of where the // generated code is located unless the code is generated at the start of // a trace, in which case it is generic and can be reused by flushing the // deferred operations in the current trace and generating a goto. int trace_count_; - BoyerMooreLookahead* bm_info_[2]; }; @@ -663,8 +731,8 @@ class Interval { return (from_ <= value) && (value <= to_); } bool is_empty() { return from_ == kNone; } - int from() const { return from_; } - int to() const { return to_; } + int from() { return from_; } + int to() { return to_; } static Interval Empty() { return Interval(); } static const int kNone = -1; private: @@ -679,20 +747,6 @@ class SeqRegExpNode: public RegExpNode { : on_success_(on_success) { } RegExpNode* on_success() { return on_success_; } void set_on_success(RegExpNode* node) { on_success_ = node; } - virtual RegExpNode* FilterASCII(int depth); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - on_success_->FillInBMInfo( - offset, recursion_depth + 1, budget - 1, bm, not_at_start); - if (offset == 0) set_bm_info(not_at_start, bm); - } - - protected: - RegExpNode* FilterSuccessor(int depth); - private: RegExpNode* on_success_; }; @@ -739,14 +793,11 @@ class ActionNode: public SeqRegExpNode { return on_success()->GetQuickCheckDetails( details, compiler, filled_in, not_at_start); } - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); Type type() { return type_; } // TODO(erikcorry): We should allow some action nodes in greedy loops. virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } + virtual ActionNode* Clone() { return new ActionNode(*this); } + virtual int ComputeFirstCharacterSet(int budget); private: union { @@ -809,15 +860,13 @@ class TextNode: public SeqRegExpNode { ZoneList<TextElement>* elements() { return elms_; } void MakeCaseIndependent(bool is_ascii); virtual int GreedyLoopTextLength(); - virtual RegExpNode* GetSuccessorOfOmnivorousTextNode( - RegExpCompiler* compiler); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); + virtual TextNode* Clone() { + TextNode* result = new TextNode(*this); + result->CalculateOffsets(); + return result; + } void CalculateOffsets(); - virtual RegExpNode* FilterASCII(int depth); + virtual int ComputeFirstCharacterSet(int budget); private: enum TextEmitPassType { @@ -848,7 +897,12 @@ class AssertionNode: public SeqRegExpNode { AT_START, AT_BOUNDARY, AT_NON_BOUNDARY, - AFTER_NEWLINE + AFTER_NEWLINE, + // Types not directly expressible in regexp syntax. + // Used for modifying a boundary node if its following character is + // known to be word and/or non-word. + AFTER_NONWORD_CHARACTER, + AFTER_WORD_CHARACTER }; static AssertionNode* AtEnd(RegExpNode* on_success) { return new AssertionNode(AT_END, on_success); @@ -874,20 +928,12 @@ class AssertionNode: public SeqRegExpNode { RegExpCompiler* compiler, int filled_in, bool not_at_start); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); + virtual int ComputeFirstCharacterSet(int budget); + virtual AssertionNode* Clone() { return new AssertionNode(*this); } AssertionNodeType type() { return type_; } void set_type(AssertionNodeType type) { type_ = type; } private: - void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace); - enum IfPrevious { kIsNonWord, kIsWord }; - void BacktrackIfPrevious(RegExpCompiler* compiler, - Trace* trace, - IfPrevious backtrack_if_previous); AssertionNode(AssertionNodeType t, RegExpNode* on_success) : SeqRegExpNode(on_success), type_(t) { } AssertionNodeType type_; @@ -915,11 +961,8 @@ class BackReferenceNode: public SeqRegExpNode { bool not_at_start) { return; } - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); + virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } + virtual int ComputeFirstCharacterSet(int budget); private: int start_reg_; @@ -943,15 +986,7 @@ class EndNode: public RegExpNode { // Returning 0 from EatsAtLeast should ensure we never get here. UNREACHABLE(); } - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - // Returning 0 from EatsAtLeast should ensure we never get here. - UNREACHABLE(); - } - + virtual EndNode* Clone() { return new EndNode(*this); } private: Action action_; }; @@ -1036,18 +1071,13 @@ class ChoiceNode: public RegExpNode { RegExpCompiler* compiler, int characters_filled_in, bool not_at_start); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); + virtual ChoiceNode* Clone() { return new ChoiceNode(*this); } bool being_calculated() { return being_calculated_; } bool not_at_start() { return not_at_start_; } void set_not_at_start() { not_at_start_ = true; } void set_being_calculated(bool b) { being_calculated_ = b; } virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; } - virtual RegExpNode* FilterASCII(int depth); protected: int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative); @@ -1059,7 +1089,7 @@ class ChoiceNode: public RegExpNode { void GenerateGuard(RegExpMacroAssembler* macro_assembler, Guard* guard, Trace* trace); - int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least); + int CalculatePreloadCharacters(RegExpCompiler* compiler, bool not_at_start); void EmitOutOfLineContinuation(RegExpCompiler* compiler, Trace* trace, GuardedAlternative alternative, @@ -1089,22 +1119,13 @@ class NegativeLookaheadChoiceNode: public ChoiceNode { RegExpCompiler* compiler, int characters_filled_in, bool not_at_start); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start) { - alternatives_->at(1).node()->FillInBMInfo( - offset, recursion_depth + 1, budget - 1, bm, not_at_start); - if (offset == 0) set_bm_info(not_at_start, bm); - } // For a negative lookahead we don't emit the quick check for the // alternative that is expected to fail. This is because quick check code // starts by loading enough characters for the alternative that takes fewest // characters, but on a negative lookahead the negative branch did not take // part in that calculation (EatsAtLeast) so the assumptions don't hold. virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } - virtual RegExpNode* FilterASCII(int depth); + virtual int ComputeFirstCharacterSet(int budget); }; @@ -1125,16 +1146,12 @@ class LoopChoiceNode: public ChoiceNode { RegExpCompiler* compiler, int characters_filled_in, bool not_at_start); - virtual void FillInBMInfo(int offset, - int recursion_depth, - int budget, - BoyerMooreLookahead* bm, - bool not_at_start); + virtual int ComputeFirstCharacterSet(int budget); + virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); } RegExpNode* loop_node() { return loop_node_; } RegExpNode* continue_node() { return continue_node_; } bool body_can_be_zero_length() { return body_can_be_zero_length_; } virtual void Accept(NodeVisitor* visitor); - virtual RegExpNode* FilterASCII(int depth); private: // AddAlternative is made private for loop nodes because alternatives @@ -1150,146 +1167,6 @@ class LoopChoiceNode: public ChoiceNode { }; -// Improve the speed that we scan for an initial point where a non-anchored -// regexp can match by using a Boyer-Moore-like table. This is done by -// identifying non-greedy non-capturing loops in the nodes that eat any -// character one at a time. For example in the middle of the regexp -// /foo[\s\S]*?bar/ we find such a loop. There is also such a loop implicitly -// inserted at the start of any non-anchored regexp. -// -// When we have found such a loop we look ahead in the nodes to find the set of -// characters that can come at given distances. For example for the regexp -// /.?foo/ we know that there are at least 3 characters ahead of us, and the -// sets of characters that can occur are [any, [f, o], [o]]. We find a range in -// the lookahead info where the set of characters is reasonably constrained. In -// our example this is from index 1 to 2 (0 is not constrained). We can now -// look 3 characters ahead and if we don't find one of [f, o] (the union of -// [f, o] and [o]) then we can skip forwards by the range size (in this case 2). -// -// For Unicode input strings we do the same, but modulo 128. -// -// We also look at the first string fed to the regexp and use that to get a hint -// of the character frequencies in the inputs. This affects the assessment of -// whether the set of characters is 'reasonably constrained'. -// -// We also have another lookahead mechanism (called quick check in the code), -// which uses a wide load of multiple characters followed by a mask and compare -// to determine whether a match is possible at this point. -enum ContainedInLattice { - kNotYet = 0, - kLatticeIn = 1, - kLatticeOut = 2, - kLatticeUnknown = 3 // Can also mean both in and out. -}; - - -inline ContainedInLattice Combine(ContainedInLattice a, ContainedInLattice b) { - return static_cast<ContainedInLattice>(a | b); -} - - -ContainedInLattice AddRange(ContainedInLattice a, - const int* ranges, - int ranges_size, - Interval new_range); - - -class BoyerMoorePositionInfo : public ZoneObject { - public: - BoyerMoorePositionInfo() - : map_(new ZoneList<bool>(kMapSize)), - map_count_(0), - w_(kNotYet), - s_(kNotYet), - d_(kNotYet), - surrogate_(kNotYet) { - for (int i = 0; i < kMapSize; i++) { - map_->Add(false); - } - } - - bool& at(int i) { return map_->at(i); } - - static const int kMapSize = 128; - static const int kMask = kMapSize - 1; - - int map_count() const { return map_count_; } - - void Set(int character); - void SetInterval(const Interval& interval); - void SetAll(); - bool is_non_word() { return w_ == kLatticeOut; } - bool is_word() { return w_ == kLatticeIn; } - - private: - ZoneList<bool>* map_; - int map_count_; // Number of set bits in the map. - ContainedInLattice w_; // The \w character class. - ContainedInLattice s_; // The \s character class. - ContainedInLattice d_; // The \d character class. - ContainedInLattice surrogate_; // Surrogate UTF-16 code units. -}; - - -class BoyerMooreLookahead : public ZoneObject { - public: - BoyerMooreLookahead(int length, RegExpCompiler* compiler); - - int length() { return length_; } - int max_char() { return max_char_; } - RegExpCompiler* compiler() { return compiler_; } - - int Count(int map_number) { - return bitmaps_->at(map_number)->map_count(); - } - - BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); } - - void Set(int map_number, int character) { - if (character > max_char_) return; - BoyerMoorePositionInfo* info = bitmaps_->at(map_number); - info->Set(character); - } - - void SetInterval(int map_number, const Interval& interval) { - if (interval.from() > max_char_) return; - BoyerMoorePositionInfo* info = bitmaps_->at(map_number); - if (interval.to() > max_char_) { - info->SetInterval(Interval(interval.from(), max_char_)); - } else { - info->SetInterval(interval); - } - } - - void SetAll(int map_number) { - bitmaps_->at(map_number)->SetAll(); - } - - void SetRest(int from_map) { - for (int i = from_map; i < length_; i++) SetAll(i); - } - bool EmitSkipInstructions(RegExpMacroAssembler* masm); - - private: - // This is the value obtained by EatsAtLeast. If we do not have at least this - // many characters left in the sample string then the match is bound to fail. - // Therefore it is OK to read a character this far ahead of the current match - // point. - int length_; - RegExpCompiler* compiler_; - // 0x7f for ASCII, 0xffff for UTF-16. - int max_char_; - ZoneList<BoyerMoorePositionInfo*>* bitmaps_; - - int GetSkipTable(int min_lookahead, - int max_lookahead, - Handle<ByteArray> boolean_skip_table); - bool FindWorthwhileInterval(int* from, int* to); - int FindBestInterval( - int max_number_of_chars, int old_biggest_points, int* from, int* to); -}; - - // There are many ways to generate code for a node. This class encapsulates // the current way we should be generating. In other words it encapsulates // the current state of the code generator. The effect of this is that we @@ -1581,7 +1458,6 @@ class RegExpEngine: public AllStatic { bool ignore_case, bool multiline, Handle<String> pattern, - Handle<String> sample_subject, bool is_ascii); static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); diff --git a/deps/v8/src/lazy-instance.h b/deps/v8/src/lazy-instance.h index 9d68b8cacc..d0893e5604 100644 --- a/deps/v8/src/lazy-instance.h +++ b/deps/v8/src/lazy-instance.h @@ -65,12 +65,8 @@ // static LazyInstance<MyClass, MyCreateTrait>::type my_instance = // LAZY_INSTANCE_INITIALIZER; // -// WARNINGS: -// - This implementation of LazyInstance is NOT THREAD-SAFE by default. See -// ThreadSafeInitOnceTrait declared below for that. -// - Lazy initialization comes with a cost. Make sure that you don't use it on -// critical path. Consider adding your initialization code to a function -// which is explicitly called once. +// WARNING: This implementation of LazyInstance is NOT thread-safe by default. +// See ThreadSafeInitOnceTrait declared below for that. // // Notes for advanced users: // LazyInstance can actually be used in two different ways: @@ -250,7 +246,7 @@ struct LazyInstance { template <typename T, - typename CreateTrait = DefaultCreateTrait<T>, + typename CreateTrait = DefaultConstructTrait<T>, typename InitOnceTrait = SingleThreadInitOnceTrait, typename DestroyTrait = LeakyInstanceTrait<T> > struct LazyDynamicInstance { diff --git a/deps/v8/src/list-inl.h b/deps/v8/src/list-inl.h index 35ee3f5e8b..7c2c83f0f7 100644 --- a/deps/v8/src/list-inl.h +++ b/deps/v8/src/list-inl.h @@ -207,19 +207,20 @@ void List<T, P>::Initialize(int capacity) { } -template <typename T, typename P> -int SortedListBSearch(const List<T>& list, P cmp) { +template <typename T> +int SortedListBSearch( + const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)) { int low = 0; int high = list.length() - 1; while (low <= high) { int mid = (low + high) / 2; T mid_elem = list[mid]; - if (cmp(&mid_elem) > 0) { + if (cmp(&mid_elem, &elem) > 0) { high = mid - 1; continue; } - if (cmp(&mid_elem) < 0) { + if (cmp(&mid_elem, &elem) < 0) { low = mid + 1; continue; } @@ -230,21 +231,9 @@ int SortedListBSearch(const List<T>& list, P cmp) { } -template<typename T> -class ElementCmp { - public: - explicit ElementCmp(T e) : elem_(e) {} - int operator()(const T* other) { - return PointerValueCompare(other, &elem_); - } - private: - T elem_; -}; - - template <typename T> int SortedListBSearch(const List<T>& list, T elem) { - return SortedListBSearch<T, ElementCmp<T> > (list, ElementCmp<T>(elem)); + return SortedListBSearch<T>(list, elem, PointerValueCompare<T>); } diff --git a/deps/v8/src/list.h b/deps/v8/src/list.h index a210dfb1b8..adddea41f0 100644 --- a/deps/v8/src/list.h +++ b/deps/v8/src/list.h @@ -173,11 +173,9 @@ typedef List<Handle<Code> > CodeHandleList; // Perform binary search for an element in an already sorted // list. Returns the index of the element of -1 if it was not found. -// |cmp| is a predicate that takes a pointer to an element of the List -// and returns +1 if it is greater, -1 if it is less than the element -// being searched. -template <typename T, class P> -int SortedListBSearch(const List<T>& list, P cmp); +template <typename T> +int SortedListBSearch( + const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)); template <typename T> int SortedListBSearch(const List<T>& list, T elem); diff --git a/deps/v8/src/lithium-allocator.cc b/deps/v8/src/lithium-allocator.cc index 9534f9e05a..4396c7354c 100644 --- a/deps/v8/src/lithium-allocator.cc +++ b/deps/v8/src/lithium-allocator.cc @@ -958,7 +958,7 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { } } - if (instr->IsMarkedAsCall()) { + if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) { for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { if (output == NULL || !output->IsDoubleRegister() || output->index() != i) { diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc index c41cce8d9d..aefd8b6492 100644 --- a/deps/v8/src/lithium.cc +++ b/deps/v8/src/lithium.cc @@ -95,37 +95,31 @@ void LOperand::PrintTo(StringStream* stream) { } #define DEFINE_OPERAND_CACHE(name, type) \ - L##name* L##name::cache = NULL; \ - \ - void L##name::SetUpCache() { \ + name* name::cache = NULL; \ + void name::SetUpCache() { \ if (cache) return; \ - cache = new L##name[kNumCachedOperands]; \ + cache = new name[kNumCachedOperands]; \ for (int i = 0; i < kNumCachedOperands; i++) { \ cache[i].ConvertTo(type, i); \ } \ } \ - \ - void L##name::TearDownCache() { \ - delete[] cache; \ - } -LITHIUM_OPERAND_LIST(DEFINE_OPERAND_CACHE) +DEFINE_OPERAND_CACHE(LConstantOperand, CONSTANT_OPERAND) +DEFINE_OPERAND_CACHE(LStackSlot, STACK_SLOT) +DEFINE_OPERAND_CACHE(LDoubleStackSlot, DOUBLE_STACK_SLOT) +DEFINE_OPERAND_CACHE(LRegister, REGISTER) +DEFINE_OPERAND_CACHE(LDoubleRegister, DOUBLE_REGISTER) + #undef DEFINE_OPERAND_CACHE void LOperand::SetUpCaches() { -#define LITHIUM_OPERAND_SETUP(name, type) L##name::SetUpCache(); - LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP) -#undef LITHIUM_OPERAND_SETUP -} - - -void LOperand::TearDownCaches() { -#define LITHIUM_OPERAND_TEARDOWN(name, type) L##name::TearDownCache(); - LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN) -#undef LITHIUM_OPERAND_TEARDOWN + LConstantOperand::SetUpCache(); + LStackSlot::SetUpCache(); + LDoubleStackSlot::SetUpCache(); + LRegister::SetUpCache(); + LDoubleRegister::SetUpCache(); } - bool LParallelMove::IsRedundant() const { for (int i = 0; i < move_operands_.length(); ++i) { if (!move_operands_[i].IsRedundant()) return false; diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h index 2ccbf56c50..d1e2e3cdef 100644 --- a/deps/v8/src/lithium.h +++ b/deps/v8/src/lithium.h @@ -35,14 +35,6 @@ namespace v8 { namespace internal { -#define LITHIUM_OPERAND_LIST(V) \ - V(ConstantOperand, CONSTANT_OPERAND) \ - V(StackSlot, STACK_SLOT) \ - V(DoubleStackSlot, DOUBLE_STACK_SLOT) \ - V(Register, REGISTER) \ - V(DoubleRegister, DOUBLE_REGISTER) - - class LOperand: public ZoneObject { public: enum Kind { @@ -60,13 +52,14 @@ class LOperand: public ZoneObject { Kind kind() const { return KindField::decode(value_); } int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } -#define LITHIUM_OPERAND_PREDICATE(name, type) \ - bool Is##name() const { return kind() == type; } - LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) - LITHIUM_OPERAND_PREDICATE(Argument, ARGUMENT) - LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED) - LITHIUM_OPERAND_PREDICATE(Ignored, INVALID) -#undef LITHIUM_OPERAND_PREDICATE + bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; } + bool IsStackSlot() const { return kind() == STACK_SLOT; } + bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; } + bool IsRegister() const { return kind() == REGISTER; } + bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; } + bool IsArgument() const { return kind() == ARGUMENT; } + bool IsUnallocated() const { return kind() == UNALLOCATED; } + bool IsIgnored() const { return kind() == INVALID; } bool Equals(LOperand* other) const { return value_ == other->value_; } void PrintTo(StringStream* stream); @@ -76,9 +69,9 @@ class LOperand: public ZoneObject { ASSERT(this->index() == index); } - // Calls SetUpCache()/TearDownCache() for each subclass. + // Calls SetUpCache() for each subclass. Don't forget to update this method + // if you add a new LOperand subclass. static void SetUpCaches(); - static void TearDownCaches(); protected: static const int kKindFieldWidth = 3; @@ -272,7 +265,6 @@ class LConstantOperand: public LOperand { } static void SetUpCache(); - static void TearDownCache(); private: static const int kNumCachedOperands = 128; @@ -308,7 +300,6 @@ class LStackSlot: public LOperand { } static void SetUpCache(); - static void TearDownCache(); private: static const int kNumCachedOperands = 128; @@ -333,7 +324,6 @@ class LDoubleStackSlot: public LOperand { } static void SetUpCache(); - static void TearDownCache(); private: static const int kNumCachedOperands = 128; @@ -358,7 +348,6 @@ class LRegister: public LOperand { } static void SetUpCache(); - static void TearDownCache(); private: static const int kNumCachedOperands = 16; @@ -383,7 +372,6 @@ class LDoubleRegister: public LOperand { } static void SetUpCache(); - static void TearDownCache(); private: static const int kNumCachedOperands = 16; diff --git a/deps/v8/src/liveedit-debugger.js b/deps/v8/src/liveedit-debugger.js index 4463c93e2a..abfb0f69c6 100644 --- a/deps/v8/src/liveedit-debugger.js +++ b/deps/v8/src/liveedit-debugger.js @@ -159,11 +159,6 @@ Debug.LiveEdit = new function() { preview_description.stack_modified = dropped_functions_number != 0; - // Our current implementation requires client to manually issue "step in" - // command for correct stack state. - preview_description.stack_update_needs_step_in = - preview_description.stack_modified; - // Start with breakpoints. Convert their line/column positions and // temporary remove. var break_points_restorer = TemporaryRemoveBreakPoints(script, change_log); diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc index d93a9d82b1..21d64df21c 100644 --- a/deps/v8/src/log.cc +++ b/deps/v8/src/log.cc @@ -1730,20 +1730,13 @@ void Logger::EnableSlidingStateWindow() { } // Protects the state below. -static Mutex* active_samplers_mutex = NULL; +static LazyMutex active_samplers_mutex = LAZY_MUTEX_INITIALIZER; List<Sampler*>* SamplerRegistry::active_samplers_ = NULL; -void SamplerRegistry::SetUp() { - if (!active_samplers_mutex) { - active_samplers_mutex = OS::CreateMutex(); - } -} - - bool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void* param) { - ScopedLock lock(active_samplers_mutex); + ScopedLock lock(active_samplers_mutex.Pointer()); for (int i = 0; ActiveSamplersExist() && i < active_samplers_->length(); ++i) { @@ -1770,7 +1763,7 @@ SamplerRegistry::State SamplerRegistry::GetState() { void SamplerRegistry::AddActiveSampler(Sampler* sampler) { ASSERT(sampler->IsActive()); - ScopedLock lock(active_samplers_mutex); + ScopedLock lock(active_samplers_mutex.Pointer()); if (active_samplers_ == NULL) { active_samplers_ = new List<Sampler*>; } else { @@ -1782,7 +1775,7 @@ void SamplerRegistry::AddActiveSampler(Sampler* sampler) { void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { ASSERT(sampler->IsActive()); - ScopedLock lock(active_samplers_mutex); + ScopedLock lock(active_samplers_mutex.Pointer()); ASSERT(active_samplers_ != NULL); bool removed = active_samplers_->RemoveElement(sampler); ASSERT(removed); diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h index 03c7b3b670..129738757e 100644 --- a/deps/v8/src/log.h +++ b/deps/v8/src/log.h @@ -437,8 +437,6 @@ class SamplerRegistry : public AllStatic { HAS_CPU_PROFILING_SAMPLERS }; - static void SetUp(); - typedef void (*VisitSampler)(Sampler*, void*); static State GetState(); diff --git a/deps/v8/src/macros.py b/deps/v8/src/macros.py index 08fa82e686..93287ae3d4 100644 --- a/deps/v8/src/macros.py +++ b/deps/v8/src/macros.py @@ -196,7 +196,6 @@ macro SET_UTC_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 1)); macro SET_LOCAL_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 0)); # Last input and last subject of regexp matches. -const LAST_SUBJECT_INDEX = 1; macro LAST_SUBJECT(array) = ((array)[1]); macro LAST_INPUT(array) = ((array)[2]); @@ -205,15 +204,6 @@ macro CAPTURE(index) = (3 + (index)); const CAPTURE0 = 3; const CAPTURE1 = 4; -# For the regexp capture override array. This has the same -# format as the arguments to a function called from -# String.prototype.replace. -macro OVERRIDE_MATCH(override) = ((override)[0]); -macro OVERRIDE_POS(override) = ((override)[(override).length - 2]); -macro OVERRIDE_SUBJECT(override) = ((override)[(override).length - 1]); -# 1-based so index of 1 returns the first capture -macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]); - # PropertyDescriptor return value indices - must match # PropertyDescriptorIndices in runtime.cc. const IS_ACCESSOR_INDEX = 0; diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc index 507ad84090..b4f488bd95 100644 --- a/deps/v8/src/mark-compact.cc +++ b/deps/v8/src/mark-compact.cc @@ -296,6 +296,8 @@ void MarkCompactCollector::CollectGarbage() { if (!collect_maps_) ReattachInitialMaps(); + heap_->isolate()->inner_pointer_to_code_cache()->Flush(); + Finish(); tracer_ = NULL; @@ -335,7 +337,6 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() { for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { MarkBit mark_bit = Marking::MarkBitFrom(obj); ASSERT(Marking::IsWhite(mark_bit)); - ASSERT_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); } } #endif @@ -372,7 +373,6 @@ void MarkCompactCollector::ClearMarkbits() { MarkBit mark_bit = Marking::MarkBitFrom(obj); mark_bit.Clear(); mark_bit.Next().Clear(); - Page::FromAddress(obj->address())->ResetLiveBytes(); } } @@ -1150,10 +1150,9 @@ class StaticMarkingVisitor : public StaticVisitorBase { JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object); // Enqueue weak map in linked list of encountered weak maps. - if (weak_map->next() == Smi::FromInt(0)) { - weak_map->set_next(collector->encountered_weak_maps()); - collector->set_encountered_weak_maps(weak_map); - } + ASSERT(weak_map->next() == Smi::FromInt(0)); + weak_map->set_next(collector->encountered_weak_maps()); + collector->set_encountered_weak_maps(weak_map); // Skip visiting the backing hash table containing the mappings. int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object); @@ -1169,15 +1168,9 @@ class StaticMarkingVisitor : public StaticVisitorBase { object_size); // Mark the backing hash table without pushing it on the marking stack. - Object* table_object = weak_map->table(); - if (!table_object->IsHashTable()) return; - ObjectHashTable* table = ObjectHashTable::cast(table_object); - Object** table_slot = - HeapObject::RawField(weak_map, JSWeakMap::kTableOffset); - MarkBit table_mark = Marking::MarkBitFrom(table); - collector->RecordSlot(table_slot, table_slot, table); - if (!table_mark.Get()) collector->SetMark(table, table_mark); - // Recording the map slot can be skipped, because maps are not compacted. + ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); + ASSERT(!MarkCompactCollector::IsMarked(table)); + collector->SetMark(table, Marking::MarkBitFrom(table)); collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); ASSERT(MarkCompactCollector::IsMarked(table->map())); } @@ -1397,12 +1390,6 @@ class StaticMarkingVisitor : public StaticVisitorBase { static void VisitSharedFunctionInfoAndFlushCode(Map* map, HeapObject* object) { - Heap* heap = map->GetHeap(); - SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); - if (shared->ic_age() != heap->global_ic_age()) { - shared->ResetForNewContext(heap->global_ic_age()); - } - MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); if (!collector->is_code_flushing_enabled()) { VisitSharedFunctionInfoGeneric(map, object); @@ -1419,6 +1406,10 @@ class StaticMarkingVisitor : public StaticVisitorBase { if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); + if (shared->ic_age() != heap->global_ic_age()) { + shared->ResetForNewContext(heap->global_ic_age()); + } + if (!known_flush_code_candidate) { known_flush_code_candidate = IsFlushable(heap, shared); if (known_flush_code_candidate) { @@ -1532,6 +1523,12 @@ class StaticMarkingVisitor : public StaticVisitorBase { JSFunction::kCodeEntryOffset + kPointerSize), HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset)); + + // Don't visit the next function list field as it is a weak reference. + Object** next_function = + HeapObject::RawField(object, JSFunction::kNextFunctionLinkOffset); + heap->mark_compact_collector()->RecordSlot( + next_function, next_function, *next_function); } static inline void VisitJSRegExpFields(Map* map, @@ -1977,7 +1974,6 @@ static inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts); static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, Page* p) { - ASSERT(!marking_deque->IsFull()); ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); @@ -2594,17 +2590,14 @@ void MarkCompactCollector::ProcessWeakMaps() { ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); - Object** anchor = reinterpret_cast<Object**>(table->address()); for (int i = 0; i < table->Capacity(); i++) { if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { - Object** key_slot = - HeapObject::RawField(table, FixedArray::OffsetOfElementAt( - ObjectHashTable::EntryToIndex(i))); - RecordSlot(anchor, key_slot, *key_slot); - Object** value_slot = - HeapObject::RawField(table, FixedArray::OffsetOfElementAt( - ObjectHashTable::EntryToValueIndex(i))); - StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot); + Object* value = table->get(table->EntryToValueIndex(i)); + StaticMarkingVisitor::VisitPointer(heap(), &value); + table->set_unchecked(heap(), + table->EntryToValueIndex(i), + value, + UPDATE_WRITE_BARRIER); } } weak_map_obj = weak_map->next(); @@ -3424,8 +3417,6 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { // under it. ProcessInvalidatedCode(&updating_visitor); - heap_->isolate()->inner_pointer_to_code_cache()->Flush(); - #ifdef DEBUG if (FLAG_verify_heap) { VerifyEvacuation(heap_); diff --git a/deps/v8/src/mark-compact.h b/deps/v8/src/mark-compact.h index f8488bb00d..66ffd19535 100644 --- a/deps/v8/src/mark-compact.h +++ b/deps/v8/src/mark-compact.h @@ -544,8 +544,6 @@ class MarkCompactCollector { void ClearMarkbits(); - bool is_compacting() const { return compacting_; } - private: MarkCompactCollector(); ~MarkCompactCollector(); diff --git a/deps/v8/src/math.js b/deps/v8/src/math.js index aee56af4f9..8e735c4a68 100644 --- a/deps/v8/src/math.js +++ b/deps/v8/src/math.js @@ -30,6 +30,7 @@ // has the added benefit that the code in this file is isolated from // changes to these properties. var $floor = MathFloor; +var $random = MathRandom; var $abs = MathAbs; // Instance class name can only be set on functions. That is the only diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc index f3dd95b851..5719d2cca3 100644 --- a/deps/v8/src/mips/code-stubs-mips.cc +++ b/deps/v8/src/mips/code-stubs-mips.cc @@ -5400,9 +5400,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ Branch(&call, ne, t0, Operand(at)); // Patch the receiver on the stack with the global receiver object. - __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); - __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); + __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); + __ sw(a2, MemOperand(sp, argc_ * kPointerSize)); __ bind(&call); } @@ -5410,12 +5410,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // a1: pushed function (to be verified) __ JumpIfSmi(a1, &non_function); // Get the map of the function object. - __ GetObjectType(a1, a3, a3); - __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); - - if (RecordCallTarget()) { - GenerateRecordCallTarget(masm); - } + __ GetObjectType(a1, a2, a2); + __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); // Fast-case: Invoke the function now. // a1: pushed function @@ -5440,17 +5436,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); - if (RecordCallTarget()) { - // If there is a call target cache, mark it megamorphic in the - // non-function case. MegamorphicSentinel is an immortal immovable - // object (undefined) so no write barrier is needed. - ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), - masm->isolate()->heap()->undefined_value()); - __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - __ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); - } // Check for function proxy. - __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); + __ Branch(&non_function, ne, a2, Operand(JS_FUNCTION_PROXY_TYPE)); __ push(a1); // Put proxy as additional argument. __ li(a0, Operand(argc_ + 1, RelocInfo::NONE)); __ li(a2, Operand(0, RelocInfo::NONE)); @@ -6106,11 +6093,37 @@ void SubStringStub::Generate(MacroAssembler* masm) { // a2: result string length __ lw(t0, FieldMemOperand(v0, String::kLengthOffset)); __ sra(t0, t0, 1); - // Return original string. __ Branch(&return_v0, eq, a2, Operand(t0)); - // Longer than original string's length or negative: unsafe arguments. - __ Branch(&runtime, hi, a2, Operand(t0)); - // Shorter than original string's length: an actual substring. + + + Label result_longer_than_two; + // Check for special case of two character ASCII string, in which case + // we do a lookup in the symbol table first. + __ li(t0, 2); + __ Branch(&result_longer_than_two, gt, a2, Operand(t0)); + __ Branch(&runtime, lt, a2, Operand(t0)); + + __ JumpIfInstanceTypeIsNotSequentialAscii(a1, a1, &runtime); + + // Get the two characters forming the sub string. + __ Addu(v0, v0, Operand(a3)); + __ lbu(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); + __ lbu(t0, FieldMemOperand(v0, SeqAsciiString::kHeaderSize + 1)); + + // Try to lookup two character string in symbol table. + Label make_two_character_string; + StringHelper::GenerateTwoCharacterSymbolTableProbe( + masm, a3, t0, a1, t1, t2, t3, t4, &make_two_character_string); + __ jmp(&return_v0); + + // a2: result string length. + // a3: two characters combined into halfword in little endian byte order. + __ bind(&make_two_character_string); + __ AllocateAsciiString(v0, a2, t0, t1, t4, &runtime); + __ sh(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); + __ jmp(&return_v0); + + __ bind(&result_longer_than_two); // Deal with different string types: update the index if necessary // and put the underlying string into t1. diff --git a/deps/v8/src/mips/constants-mips.h b/deps/v8/src/mips/constants-mips.h index 3d585717cb..fd04722792 100644 --- a/deps/v8/src/mips/constants-mips.h +++ b/deps/v8/src/mips/constants-mips.h @@ -788,6 +788,11 @@ const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; const int kBranchReturnOffset = 2 * Instruction::kInstrSize; +const int kDoubleAlignmentBits = 3; +const int kDoubleAlignment = (1 << kDoubleAlignmentBits); +const int kDoubleAlignmentMask = kDoubleAlignment - 1; + + } } // namespace v8::internal #endif // #ifndef V8_MIPS_CONSTANTS_H_ diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc index 7be50569cd..4b58fc8c14 100644 --- a/deps/v8/src/mips/full-codegen-mips.cc +++ b/deps/v8/src/mips/full-codegen-mips.cc @@ -120,6 +120,13 @@ class JumpPatchSite BASE_EMBEDDED { }; +// TODO(jkummerow): Obsolete as soon as x64 is updated. Remove. +int FullCodeGenerator::self_optimization_header_size() { + UNREACHABLE(); + return 10 * Instruction::kInstrSize; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right. The actual // argument count matches the formal parameter count expected by the @@ -275,11 +282,11 @@ void FullCodeGenerator::Generate() { // For named function expressions, declare the function name as a // constant. if (scope()->is_function_scope() && scope()->function() != NULL) { - VariableDeclaration* function = scope()->function(); - ASSERT(function->proxy()->var()->mode() == CONST || - function->proxy()->var()->mode() == CONST_HARMONY); - ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); - VisitVariableDeclaration(function); + VariableProxy* proxy = scope()->function(); + ASSERT(proxy->var()->mode() == CONST || + proxy->var()->mode() == CONST_HARMONY); + ASSERT(proxy->var()->location() != Variable::UNALLOCATED); + EmitDeclaration(proxy, proxy->var()->mode(), NULL); } VisitDeclarations(scope()->declarations()); } @@ -789,53 +796,64 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, } -void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { - // The variable in the declaration always resides in the current function - // context. - ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); - if (FLAG_debug_code) { - // Check that we're not inside a with or catch context. - __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset)); - __ LoadRoot(t0, Heap::kWithContextMapRootIndex); - __ Check(ne, "Declaration in with context.", - a1, Operand(t0)); - __ LoadRoot(t0, Heap::kCatchContextMapRootIndex); - __ Check(ne, "Declaration in catch context.", - a1, Operand(t0)); - } -} - - -void FullCodeGenerator::VisitVariableDeclaration( - VariableDeclaration* declaration) { +void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function) { // If it was not possible to allocate the variable at compile time, we // need to "declare" it at runtime to make sure it actually exists in the // local context. - VariableProxy* proxy = declaration->proxy(); - VariableMode mode = declaration->mode(); Variable* variable = proxy->var(); - bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; + bool binding_needs_init = (function == NULL) && + (mode == CONST || mode == CONST_HARMONY || mode == LET); switch (variable->location()) { case Variable::UNALLOCATED: - globals_->Add(variable->name()); - globals_->Add(variable->binding_needs_init() - ? isolate()->factory()->the_hole_value() - : isolate()->factory()->undefined_value()); + ++global_count_; break; case Variable::PARAMETER: case Variable::LOCAL: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); - __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); - __ sw(t0, StackOperand(variable)); + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ sw(result_register(), StackOperand(variable)); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); + __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); + __ sw(t0, StackOperand(variable)); } break; case Variable::CONTEXT: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); - EmitDebugCheckDeclarationContext(variable); + // The variable in the decl always resides in the current function + // context. + ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); + if (FLAG_debug_code) { + // Check that we're not inside a with or catch context. + __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset)); + __ LoadRoot(t0, Heap::kWithContextMapRootIndex); + __ Check(ne, "Declaration in with context.", + a1, Operand(t0)); + __ LoadRoot(t0, Heap::kCatchContextMapRootIndex); + __ Check(ne, "Declaration in catch context.", + a1, Operand(t0)); + } + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ sw(result_register(), ContextOperand(cp, variable->index())); + int offset = Context::SlotOffset(variable->index()); + // We know that we have written a function, which is not a smi. + __ RecordWriteContextSlot(cp, + offset, + result_register(), + a2, + kRAHasBeenSaved, + kDontSaveFPRegs, + EMIT_REMEMBERED_SET, + OMIT_SMI_CHECK); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ sw(at, ContextOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. @@ -844,11 +862,13 @@ void FullCodeGenerator::VisitVariableDeclaration( break; case Variable::LOOKUP: { - Comment cmnt(masm_, "[ VariableDeclaration"); + Comment cmnt(masm_, "[ Declaration"); __ li(a2, Operand(variable->name())); // Declaration nodes are always introduced in one of four modes. - ASSERT(mode == VAR || mode == LET || - mode == CONST || mode == CONST_HARMONY); + ASSERT(mode == VAR || + mode == CONST || + mode == CONST_HARMONY || + mode == LET); PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE; __ li(a1, Operand(Smi::FromInt(attr))); @@ -856,9 +876,13 @@ void FullCodeGenerator::VisitVariableDeclaration( // Note: For variables we must not push an initial value (such as // 'undefined') because we may have a (legal) redeclaration and we // must not destroy the current value. - if (hole_init) { - __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); - __ Push(cp, a2, a1, a0); + if (function != NULL) { + __ Push(cp, a2, a1); + // Push initial value for function declaration. + VisitForStackValue(function); + } else if (binding_needs_init) { + __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); + __ Push(cp, a2, a1, a0); } else { ASSERT(Smi::FromInt(0) == 0); __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. @@ -871,122 +895,6 @@ void FullCodeGenerator::VisitVariableDeclaration( } -void FullCodeGenerator::VisitFunctionDeclaration( - FunctionDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: { - globals_->Add(variable->name()); - Handle<SharedFunctionInfo> function = - Compiler::BuildFunctionInfo(declaration->fun(), script()); - // Check for stack-overflow exception. - if (function.is_null()) return SetStackOverflow(); - globals_->Add(function); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - VisitForAccumulatorValue(declaration->fun()); - __ sw(result_register(), StackOperand(variable)); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - EmitDebugCheckDeclarationContext(variable); - VisitForAccumulatorValue(declaration->fun()); - __ sw(result_register(), ContextOperand(cp, variable->index())); - int offset = Context::SlotOffset(variable->index()); - // We know that we have written a function, which is not a smi. - __ RecordWriteContextSlot(cp, - offset, - result_register(), - a2, - kRAHasBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), NO_REGISTERS); - break; - } - - case Variable::LOOKUP: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - __ li(a2, Operand(variable->name())); - __ li(a1, Operand(Smi::FromInt(NONE))); - __ Push(cp, a2, a1); - // Push initial value for function declaration. - VisitForStackValue(declaration->fun()); - __ CallRuntime(Runtime::kDeclareContextSlot, 4); - break; - } - } -} - - -void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - Handle<JSModule> instance = declaration->module()->interface()->Instance(); - ASSERT(!instance.is_null()); - - switch (variable->location()) { - case Variable::UNALLOCATED: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - globals_->Add(variable->name()); - globals_->Add(instance); - Visit(declaration->module()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - EmitDebugCheckDeclarationContext(variable); - __ li(a1, Operand(instance)); - __ sw(a1, ContextOperand(cp, variable->index())); - Visit(declaration->module()); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: - // TODO(rossberg) - break; - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ImportDeclaration"); - EmitDebugCheckDeclarationContext(variable); - // TODO(rossberg) - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { - // TODO(rossberg) -} - - void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { // Call the runtime to declare the globals. // The context is the first argument. @@ -2388,18 +2296,6 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - - // Record call targets in unoptimized code, but not in the snapshot. - if (!Serializer::enabled()) { - flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); - Handle<Object> uninitialized = - TypeFeedbackCells::UninitializedSentinel(isolate()); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); - RecordTypeFeedbackCell(expr->id(), cell); - __ li(a2, Operand(cell)); - } - CallFunctionStub stub(arg_count, flags); __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); __ CallStub(&stub); @@ -3088,7 +2984,7 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { __ Move(f14, zero_reg, a1); // Subtract and store the result in the heap number. __ sub_d(f0, f12, f14); - __ sdc1(f0, FieldMemOperand(s0, HeapNumber::kValueOffset)); + __ sdc1(f0, MemOperand(s0, HeapNumber::kValueOffset - kHeapObjectTag)); __ mov(v0, s0); } else { __ PrepareCallCFunction(2, a0); @@ -4497,8 +4393,7 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) { void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { Scope* declaration_scope = scope()->DeclarationScope(); - if (declaration_scope->is_global_scope() || - declaration_scope->is_module_scope()) { + if (declaration_scope->is_global_scope()) { // Contexts nested in the global context have a canonical empty function // as their closure, not the anonymous closure containing the global // code. Pass a smi sentinel and let the runtime look up the empty diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc index 122fd1ef4c..f21ed8f3ee 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.cc +++ b/deps/v8/src/mips/lithium-codegen-mips.cc @@ -2139,7 +2139,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RelocInfo::CODE_TARGET, instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Put the result value into the result register slot and // restore all registers. @@ -2650,20 +2651,16 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register temp = scratch1(); Register result = ToRegister(instr->result()); - if (instr->hydrogen()->from_inlined()) { - __ Subu(result, sp, 2 * kPointerSize); - } else { - // Check if the calling frame is an arguments adaptor frame. - Label done, adapted; - __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); - __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); - - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). - __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). - } + // Check if the calling frame is an arguments adaptor frame. + Label done, adapted; + __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); + __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); + __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). + __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). } @@ -2771,7 +2768,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { __ sll(scratch, length, 2); __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -2796,11 +2793,6 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } -void LCodeGen::DoDrop(LDrop* instr) { - __ Drop(instr->count()); -} - - void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); @@ -2846,8 +2838,7 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - A1State a1_state) { + CallKind call_kind) { bool can_invoke_directly = !function->NeedsArgumentsAdaption() || function->shared()->formal_parameter_count() == arity; @@ -2855,10 +2846,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, RecordPosition(pointers->position()); if (can_invoke_directly) { - if (a1_state == A1_UNINITIALIZED) { - __ LoadHeapObject(a1, function); - } - + __ LoadHeapObject(a1, function); // Change context if needed. bool change_context = (info()->closure()->context() != function->context()) || @@ -2895,11 +2883,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { ASSERT(ToRegister(instr->result()).is(v0)); __ mov(a0, v0); - CallKnownFunction(instr->function(), - instr->arity(), - instr, - CALL_AS_METHOD, - A1_UNINITIALIZED); + CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD); } @@ -3335,21 +3319,13 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->function()).is(a1)); ASSERT(instr->HasPointerMap()); - - if (instr->known_function().is_null()) { - LPointerMap* pointers = instr->pointer_map(); - RecordPosition(pointers->position()); - SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); - ParameterCount count(instr->arity()); - __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); - __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - } else { - CallKnownFunction(instr->known_function(), - instr->arity(), - instr, - CALL_AS_METHOD, - A1_CONTAINS_TARGET); - } + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + RecordPosition(pointers->position()); + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); + ParameterCount count(instr->arity()); + __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } @@ -3404,11 +3380,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(v0)); - CallKnownFunction(instr->target(), - instr->arity(), - instr, - CALL_AS_FUNCTION, - A1_UNINITIALIZED); + CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); } @@ -3564,16 +3536,14 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); } - if (instr->NeedsCanonicalization()) { - Label is_nan; - // Check for NaN. All NaNs must be canonicalized. - __ BranchF(NULL, &is_nan, eq, value, value); - __ Branch(¬_nan); + Label is_nan; + // Check for NaN. All NaNs must be canonicalized. + __ BranchF(NULL, &is_nan, eq, value, value); + __ Branch(¬_nan); - // Only load canonical NaN if the comparison above set the overflow. - __ bind(&is_nan); - __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); - } + // Only load canonical NaN if the comparison above set the overflow. + __ bind(&is_nan); + __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); __ bind(¬_nan); __ sdc1(value, MemOperand(scratch)); @@ -4265,21 +4235,14 @@ void LCodeGen::DoCheckMapCommon(Register reg, } -void LCodeGen::DoCheckMaps(LCheckMaps* instr) { +void LCodeGen::DoCheckMap(LCheckMap* instr) { Register scratch = scratch0(); LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); - Label success; - SmallMapList* map_set = instr->hydrogen()->map_set(); - for (int i = 0; i < map_set->length() - 1; i++) { - Handle<Map> map = map_set->at(i); - __ CompareMapAndBranch( - reg, scratch, map, &success, eq, &success, REQUIRE_EXACT_MAP); - } - Handle<Map> map = map_set->last(); - DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); - __ bind(&success); + Handle<Map> map = instr->hydrogen()->map(); + DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(), + instr->environment()); } @@ -4395,14 +4358,6 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { deferred->entry(), TAG_OBJECT); - __ bind(deferred->exit()); - if (FLAG_debug_code) { - Label is_in_new_space; - __ JumpIfInNewSpace(result, scratch, &is_in_new_space); - __ Abort("Allocated object is not in new-space"); - __ bind(&is_in_new_space); - } - // Load the initial map. Register map = scratch; __ LoadHeapObject(map, constructor); @@ -4421,14 +4376,14 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { __ sw(scratch, FieldMemOperand(result, property_offset)); } } + + __ bind(deferred->exit()); } void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); - int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the // result register contain a valid pointer because it is already @@ -4436,9 +4391,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { __ mov(result, zero_reg); PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - __ li(a0, Operand(Smi::FromInt(instance_size))); + __ LoadHeapObject(a0, constructor); __ push(a0); - CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); + CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr); __ StoreToSafepointRegisterSlot(v0, result); } @@ -4574,10 +4529,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ sw(a2, FieldMemOperand(result, total_offset + 4)); } } else if (elements->IsFixedArray()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); for (int i = 0; i < elements_length; i++) { int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(object, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); __ Addu(a2, result, Operand(*offset)); @@ -4601,23 +4555,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, void LCodeGen::DoFastLiteral(LFastLiteral* instr) { int size = instr->hydrogen()->total_size(); - ElementsKind boilerplate_elements_kind = - instr->hydrogen()->boilerplate()->GetElementsKind(); - - // Deopt if the literal boilerplate ElementsKind is of a type different than - // the expected one. The check isn't necessary if the boilerplate has already - // been converted to FAST_ELEMENTS. - if (boilerplate_elements_kind != FAST_ELEMENTS) { - __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); - // Load map into a2. - __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); - // Load the map's "bit field 2". - __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); - // Retrieve elements_kind from bit field 2. - __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); - DeoptimizeIf(ne, instr->environment(), a2, - Operand(boilerplate_elements_kind)); - } // Allocate all objects that are part of the literal in one big // allocation. This avoids multiple limit checks. @@ -4953,7 +4890,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { Register strict = scratch0(); __ li(strict, Operand(Smi::FromInt(strict_mode_flag()))); __ Push(object, key, strict); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -4966,7 +4903,7 @@ void LCodeGen::DoIn(LIn* instr) { Register obj = ToRegister(instr->object()); Register key = ToRegister(instr->key()); __ Push(key, obj); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h index 94bb945b31..b5082561e0 100644 --- a/deps/v8/src/mips/lithium-codegen-mips.h +++ b/deps/v8/src/mips/lithium-codegen-mips.h @@ -212,18 +212,12 @@ class LCodeGen BASE_EMBEDDED { int argc, LInstruction* instr); - enum A1State { - A1_UNINITIALIZED, - A1_CONTAINS_TARGET - }; - // Generate a direct call to a known function. Expects the function // to be in a1. void CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - A1State a1_state); + CallKind call_kind); void LoadHeapObject(Register result, Handle<HeapObject> object); diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc index 1eb3ab7a0e..32c8875853 100644 --- a/deps/v8/src/mips/lithium-mips.cc +++ b/deps/v8/src/mips/lithium-mips.cc @@ -108,17 +108,22 @@ void LInstruction::PrintTo(StringStream* stream) { } -void LInstruction::PrintDataTo(StringStream* stream) { +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { stream->Add("= "); - for (int i = 0; i < InputCount(); i++) { + for (int i = 0; i < inputs_.length(); i++) { if (i > 0) stream->Add(" "); - InputAt(i)->PrintTo(stream); + inputs_[i]->PrintTo(stream); } } -void LInstruction::PrintOutputOperandTo(StringStream* stream) { - if (HasResult()) result()->PrintTo(stream); +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { + for (int i = 0; i < results_.length(); i++) { + if (i > 0) stream->Add(" "); + results_[i]->PrintTo(stream); + } } @@ -727,6 +732,22 @@ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { } +LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id) { + ASSERT(instruction_pending_deoptimization_environment_ == NULL); + ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); + instruction_pending_deoptimization_environment_ = instr; + pending_deoptimization_ast_id_ = ast_id; + return instr; +} + + +void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { + instruction_pending_deoptimization_environment_ = NULL; + pending_deoptimization_ast_id_ = AstNode::kNoNumber; +} + + LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize) { @@ -739,10 +760,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, if (hinstr->HasObservableSideEffects()) { ASSERT(hinstr->next()->IsSimulate()); HSimulate* sim = HSimulate::cast(hinstr->next()); - ASSERT(instruction_pending_deoptimization_environment_ == NULL); - ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); - instruction_pending_deoptimization_environment_ = instr; - pending_deoptimization_ast_id_ = sim->ast_id(); + instr = SetInstructionPendingDeoptimizationEnvironment( + instr, sim->ast_id()); } // If instruction does not have side-effects lazy deoptimization @@ -760,6 +779,12 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, } +LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { + instr->MarkAsSaveDoubles(); + return instr; +} + + LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { ASSERT(!instr->HasPointerMap()); instr->set_pointer_map(new(zone()) LPointerMap(position_)); @@ -1271,7 +1296,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; LOperand* value = UseRegisterAtStart(instr->value()); return DefineAsRegister(new(zone()) LBitNotI(value)); } @@ -1296,12 +1320,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { } -LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { - UNIMPLEMENTED(); - return NULL; -} - - LInstruction* LChunkBuilder::DoMod(HMod* instr) { if (instr->representation().IsInteger32()) { ASSERT(instr->left()->representation().IsInteger32()); @@ -1736,9 +1754,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { } -LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { +LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - LInstruction* result = new(zone()) LCheckMaps(value); + LInstruction* result = new(zone()) LCheckMap(value); return AssignEnvironment(result); } @@ -2229,12 +2247,9 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { if (pending_deoptimization_ast_id_ == instr->ast_id()) { LInstruction* result = new(zone()) LLazyBailout; result = AssignEnvironment(result); - // Store the lazy deopt environment with the instruction if needed. Right - // now it is only used for LInstanceOfKnownGlobal. instruction_pending_deoptimization_environment_-> - SetDeferredLazyDeoptimizationEnvironment(result->environment()); - instruction_pending_deoptimization_environment_ = NULL; - pending_deoptimization_ast_id_ = AstNode::kNoNumber; + set_deoptimization_environment(result->environment()); + ClearInstructionPendingDeoptimizationEnvironment(); return result; } @@ -2261,8 +2276,8 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { undefined, instr->call_kind(), instr->is_construct()); - if (instr->arguments_var() != NULL) { - inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject()); + if (instr->arguments() != NULL) { + inner->Bind(instr->arguments(), graph()->GetArgumentsObject()); } current_block_->UpdateEnvironment(inner); chunk_->AddInlinedClosure(instr->closure()); @@ -2271,21 +2286,10 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { - LInstruction* pop = NULL; - - HEnvironment* env = current_block_->last_environment(); - - if (instr->arguments_pushed()) { - int argument_count = env->arguments_environment()->parameter_count(); - pop = new(zone()) LDrop(argument_count); - argument_count_ -= argument_count; - } - HEnvironment* outer = current_block_->last_environment()-> DiscardInlined(false); current_block_->UpdateEnvironment(outer); - - return pop; + return NULL; } diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h index a04b42961a..5a7bf4d941 100644 --- a/deps/v8/src/mips/lithium-mips.h +++ b/deps/v8/src/mips/lithium-mips.h @@ -71,7 +71,7 @@ class LCodeGen; V(CallStub) \ V(CheckFunction) \ V(CheckInstanceType) \ - V(CheckMaps) \ + V(CheckMap) \ V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ @@ -179,8 +179,7 @@ class LCodeGen; V(CheckMapValue) \ V(LoadFieldByIndex) \ V(DateField) \ - V(WrapReceiver) \ - V(Drop) + V(WrapReceiver) #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ virtual Opcode opcode() const { return LInstruction::k##type; } \ @@ -203,14 +202,15 @@ class LInstruction: public ZoneObject { LInstruction() : environment_(NULL), hydrogen_value_(NULL), - is_call_(false) { } + is_call_(false), + is_save_doubles_(false) { } virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; virtual const char* Mnemonic() const = 0; virtual void PrintTo(StringStream* stream); - virtual void PrintDataTo(StringStream* stream); - virtual void PrintOutputOperandTo(StringStream* stream); + virtual void PrintDataTo(StringStream* stream) = 0; + virtual void PrintOutputOperandTo(StringStream* stream) = 0; enum Opcode { // Declare a unique enum value for each instruction. @@ -245,12 +245,22 @@ class LInstruction: public ZoneObject { void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } + void set_deoptimization_environment(LEnvironment* env) { + deoptimization_environment_.set(env); + } + LEnvironment* deoptimization_environment() const { + return deoptimization_environment_.get(); + } + bool HasDeoptimizationEnvironment() const { + return deoptimization_environment_.is_set(); + } void MarkAsCall() { is_call_ = true; } + void MarkAsSaveDoubles() { is_save_doubles_ = true; } // Interface to the register allocator and iterators. bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; } virtual bool HasResult() const = 0; virtual LOperand* result() = 0; @@ -271,6 +281,7 @@ class LInstruction: public ZoneObject { LEnvironment* environment_; SetOncePointer<LPointerMap> pointer_map_; HValue* hydrogen_value_; + SetOncePointer<LEnvironment> deoptimization_environment_; bool is_call_; bool is_save_doubles_; }; @@ -294,6 +305,9 @@ class LTemplateInstruction: public LInstruction { int TempCount() { return T; } LOperand* TempAt(int i) { return temps_[i]; } + virtual void PrintDataTo(StringStream* stream); + virtual void PrintOutputOperandTo(StringStream* stream); + protected: EmbeddedContainer<LOperand*, R> results_; EmbeddedContainer<LOperand*, I> inputs_; @@ -519,8 +533,9 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { public: + LArgumentsElements() { } + DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") - DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) }; @@ -818,15 +833,6 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) Handle<JSFunction> function() const { return hydrogen()->function(); } - LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { - return lazy_deopt_env_; - } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { - lazy_deopt_env_ = env; - } - - private: - LEnvironment* lazy_deopt_env_; }; @@ -1352,19 +1358,6 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; -class LDrop: public LTemplateInstruction<0, 0, 0> { - public: - explicit LDrop(int count) : count_(count) { } - - int count() const { return count_; } - - DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") - - private: - int count_; -}; - - class LThisFunction: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") @@ -1447,7 +1440,6 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { virtual void PrintDataTo(StringStream* stream); int arity() const { return hydrogen()->argument_count() - 1; } - Handle<JSFunction> known_function() { return hydrogen()->known_function(); } }; @@ -1727,8 +1719,6 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - - bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; @@ -1879,14 +1869,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> { }; -class LCheckMaps: public LTemplateInstruction<0, 1, 0> { +class LCheckMap: public LTemplateInstruction<0, 1, 0> { public: - explicit LCheckMaps(LOperand* value) { + explicit LCheckMap(LOperand* value) { inputs_[0] = value; } - DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") - DECLARE_HYDROGEN_ACCESSOR(CheckMaps) + DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") + DECLARE_HYDROGEN_ACCESSOR(CheckMap) }; @@ -2359,6 +2349,11 @@ class LChunkBuilder BASE_EMBEDDED { LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); + LInstruction* MarkAsSaveDoubles(LInstruction* instr); + + LInstruction* SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id); + void ClearInstructionPendingDeoptimizationEnvironment(); LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, int* argument_index_accumulator); diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.cc b/deps/v8/src/mips/regexp-macro-assembler-mips.cc index c48bcc497e..ae4da936ce 100644 --- a/deps/v8/src/mips/regexp-macro-assembler-mips.cc +++ b/deps/v8/src/mips/regexp-macro-assembler-mips.cc @@ -158,7 +158,7 @@ int RegExpMacroAssemblerMIPS::stack_limit_slack() { void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) { if (by != 0) { __ Addu(current_input_offset(), - current_input_offset(), Operand(by * char_size())); + current_input_offset(), Operand(by * char_size())); } } @@ -229,9 +229,9 @@ void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str, - int cp_offset, - Label* on_failure, - bool check_end_of_string) { + int cp_offset, + Label* on_failure, + bool check_end_of_string) { if (on_failure == NULL) { // Instead of inlining a backtrack for each test, (re)use the global // backtrack target. @@ -452,26 +452,24 @@ void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1, void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, - Label* on_not_equal) { + Label* on_not_equal) { BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); } void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c, - uint32_t mask, - Label* on_equal) { + uint32_t mask, + Label* on_equal) { __ And(a0, current_character(), Operand(mask)); - Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); - BranchOrBacktrack(on_equal, eq, a0, rhs); + BranchOrBacktrack(on_equal, eq, a0, Operand(c)); } void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c, - uint32_t mask, - Label* on_not_equal) { + uint32_t mask, + Label* on_not_equal) { __ And(a0, current_character(), Operand(mask)); - Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c); - BranchOrBacktrack(on_not_equal, ne, a0, rhs); + BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); } @@ -480,51 +478,12 @@ void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd( uc16 minus, uc16 mask, Label* on_not_equal) { - ASSERT(minus < String::kMaxUtf16CodeUnit); - __ Subu(a0, current_character(), Operand(minus)); - __ And(a0, a0, Operand(mask)); - BranchOrBacktrack(on_not_equal, ne, a0, Operand(c)); -} - - -void RegExpMacroAssemblerMIPS::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - __ Subu(a0, current_character(), Operand(from)); - // Unsigned lower-or-same condition. - BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from)); -} - - -void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - __ Subu(a0, current_character(), Operand(from)); - // Unsigned higher condition. - BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from)); -} - - -void RegExpMacroAssemblerMIPS::CheckBitInTable( - Handle<ByteArray> table, - Label* on_bit_set) { - __ li(a0, Operand(table)); - if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { - __ And(a1, current_character(), Operand(kTableSize - 1)); - __ Addu(a0, a0, a1); - } else { - __ Addu(a0, a0, current_character()); - } - - __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize)); - BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg)); + UNIMPLEMENTED_MIPS(); } bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type, - Label* on_no_match) { + Label* on_no_match) { // Range checks (c in min..max) are generally implemented by an unsigned // (c - min) <= (max - min) check. switch (type) { @@ -889,23 +848,23 @@ void RegExpMacroAssemblerMIPS::GoTo(Label* to) { void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg, - int comparand, - Label* if_ge) { + int comparand, + Label* if_ge) { __ lw(a0, register_location(reg)); BranchOrBacktrack(if_ge, ge, a0, Operand(comparand)); } void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg, - int comparand, - Label* if_lt) { + int comparand, + Label* if_lt) { __ lw(a0, register_location(reg)); BranchOrBacktrack(if_lt, lt, a0, Operand(comparand)); } void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg, - Label* if_eq) { + Label* if_eq) { __ lw(a0, register_location(reg)); BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset())); } @@ -918,9 +877,9 @@ RegExpMacroAssembler::IrregexpImplementation void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, - Label* on_end_of_input, - bool check_bounds, - int characters) { + Label* on_end_of_input, + bool check_bounds, + int characters) { ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works). if (check_bounds) { @@ -971,7 +930,7 @@ void RegExpMacroAssemblerMIPS::PushCurrentPosition() { void RegExpMacroAssemblerMIPS::PushRegister(int register_index, - StackCheckFlag check_stack_limit) { + StackCheckFlag check_stack_limit) { __ lw(a0, register_location(register_index)); Push(a0); if (check_stack_limit) CheckStackLimit(); @@ -1018,7 +977,7 @@ void RegExpMacroAssemblerMIPS::Succeed() { void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg, - int cp_offset) { + int cp_offset) { if (cp_offset == 0) { __ sw(current_input_offset(), register_location(reg)); } else { @@ -1175,7 +1134,7 @@ MemOperand RegExpMacroAssemblerMIPS::register_location(int register_index) { void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, - Label* on_outside_input) { + Label* on_outside_input) { BranchOrBacktrack(on_outside_input, ge, current_input_offset(), @@ -1203,10 +1162,8 @@ void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, } -void RegExpMacroAssemblerMIPS::SafeCall(Label* to, - Condition cond, - Register rs, - const Operand& rt) { +void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs, + const Operand& rt) { __ BranchAndLink(to, cond, rs, rt); } @@ -1277,7 +1234,7 @@ void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub( void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset, - int characters) { + int characters) { Register offset = current_input_offset(); if (cp_offset != 0) { __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.h b/deps/v8/src/mips/regexp-macro-assembler-mips.h index d167f624b6..d42d4cf67e 100644 --- a/deps/v8/src/mips/regexp-macro-assembler-mips.h +++ b/deps/v8/src/mips/regexp-macro-assembler-mips.h @@ -81,14 +81,6 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler { uc16 minus, uc16 mask, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); - // Checks whether the given offset from the current position is before // the end of the string. virtual void CheckPosition(int cp_offset, Label* on_outside_input); diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc index 676b523e23..54f55b3ceb 100644 --- a/deps/v8/src/mips/stub-cache-mips.cc +++ b/deps/v8/src/mips/stub-cache-mips.cc @@ -565,8 +565,6 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ Push(scratch, receiver, holder); __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); __ push(scratch); - __ li(scratch, Operand(ExternalReference::isolate_address())); - __ push(scratch); } @@ -581,7 +579,7 @@ static void CompileCallLoadPropertyWithInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()); - __ PrepareCEntryArgs(6); + __ PrepareCEntryArgs(5); __ PrepareCEntryFunction(ref); CEntryStub stub(1); @@ -589,10 +587,10 @@ static void CompileCallLoadPropertyWithInterceptor( } -static const int kFastApiCallArguments = 4; +static const int kFastApiCallArguments = 3; -// Reserves space for the extra arguments to API function in the +// Reserves space for the extra arguments to FastHandleApiCall in the // caller's frame. // // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. @@ -618,8 +616,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // -- sp[0] : holder (set by CheckPrototypes) // -- sp[4] : callee JS function // -- sp[8] : call data - // -- sp[12] : isolate - // -- sp[16] : last JS argument + // -- sp[12] : last JS argument // -- ... // -- sp[(argc + 3) * 4] : first JS argument // -- sp[(argc + 4) * 4] : receiver @@ -629,7 +626,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, __ LoadHeapObject(t1, function); __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); - // Pass the additional arguments. + // Pass the additional arguments FastHandleApiCall expects. Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); Handle<Object> call_data(api_call_info->data()); if (masm->isolate()->heap()->InNewSpace(*call_data)) { @@ -639,17 +636,14 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, __ li(t2, call_data); } - __ li(t3, Operand(ExternalReference::isolate_address())); - // Store JS function, call data and isolate. + // Store JS function and call data. __ sw(t1, MemOperand(sp, 1 * kPointerSize)); __ sw(t2, MemOperand(sp, 2 * kPointerSize)); - __ sw(t3, MemOperand(sp, 3 * kPointerSize)); - // Prepare arguments. - __ Addu(a2, sp, Operand(3 * kPointerSize)); + // a2 points to call data as expected by Arguments + // (refer to layout above). + __ Addu(a2, sp, Operand(2 * kPointerSize)); - // Allocate the v8::Arguments structure in the arguments' space since - // it's not controlled by GC. const int kApiStackSpace = 4; FrameScope frame_scope(masm, StackFrame::MANUAL); @@ -664,9 +658,9 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // Arguments is built at sp + 1 (sp is a reserved spot for ra). __ Addu(a1, sp, kPointerSize); - // v8::Arguments::implicit_args_ + // v8::Arguments::implicit_args = data __ sw(a2, MemOperand(a1, 0 * kPointerSize)); - // v8::Arguments::values_ + // v8::Arguments::values = last argument __ Addu(t0, a2, Operand(argc * kPointerSize)); __ sw(t0, MemOperand(a1, 1 * kPointerSize)); // v8::Arguments::length_ = argc @@ -844,7 +838,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 6); + 5); // Restore the name_ register. __ pop(name_); // Leave the internal frame. @@ -1212,13 +1206,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, } else { __ li(scratch3, Handle<Object>(callback->data())); } - __ Subu(sp, sp, 4 * kPointerSize); - __ sw(reg, MemOperand(sp, 3 * kPointerSize)); - __ sw(scratch3, MemOperand(sp, 2 * kPointerSize)); - __ li(scratch3, Operand(ExternalReference::isolate_address())); - __ sw(scratch3, MemOperand(sp, 1 * kPointerSize)); - __ sw(name_reg, MemOperand(sp, 0 * kPointerSize)); - + __ Push(reg, scratch3, name_reg); __ mov(a2, scratch2); // Saved in case scratch2 == a1. __ mov(a1, sp); // a1 (first argument - see note below) = Handle<String> @@ -1237,7 +1225,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, // a2 (second argument - see note above) = AccessorInfo& __ Addu(a2, sp, kPointerSize); - const int kStackUnwindSpace = 5; + const int kStackUnwindSpace = 4; Address getter_address = v8::ToCData<Address>(callback->getter()); ApiFunction fun(getter_address); ExternalReference ref = @@ -1353,17 +1341,24 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, // Important invariant in CALLBACKS case: the code above must be // structured to never clobber |receiver| register. __ li(scratch2, callback); - - __ Push(receiver, holder_reg); - __ lw(scratch3, - FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); - __ li(scratch1, Operand(ExternalReference::isolate_address())); - __ Push(scratch3, scratch1, scratch2, name_reg); + // holder_reg is either receiver or scratch1. + if (!receiver.is(holder_reg)) { + ASSERT(scratch1.is(holder_reg)); + __ Push(receiver, holder_reg); + __ lw(scratch3, + FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); + __ Push(scratch3, scratch2, name_reg); + } else { + __ push(receiver); + __ lw(scratch3, + FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); + __ Push(holder_reg, scratch3, scratch2, name_reg); + } ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), masm()->isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1376,7 +1371,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } @@ -1743,14 +1738,14 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall( // expensive shift first, and use an offset later on. __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize); __ Addu(elements, elements, t1); - __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize)); + __ lw(v0, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); __ Branch(&call_builtin, eq, v0, Operand(t2)); // Set the array's length. __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); // Fill with the hole. - __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); + __ sw(t2, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); __ Drop(argc + 1); __ Ret(); @@ -3377,45 +3372,6 @@ static bool IsElementTypeSigned(ElementsKind elements_kind) { } -static void GenerateSmiKeyCheck(MacroAssembler* masm, - Register key, - Register scratch0, - Register scratch1, - FPURegister double_scratch0, - Label* fail) { - if (CpuFeatures::IsSupported(FPU)) { - CpuFeatures::Scope scope(FPU); - Label key_ok; - // Check for smi or a smi inside a heap number. We convert the heap - // number and check if the conversion is exact and fits into the smi - // range. - __ JumpIfSmi(key, &key_ok); - __ CheckMap(key, - scratch0, - Heap::kHeapNumberMapRootIndex, - fail, - DONT_DO_SMI_CHECK); - __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); - __ EmitFPUTruncate(kRoundToZero, - double_scratch0, - double_scratch0, - scratch0, - scratch1, - kCheckForInexactConversion); - - __ Branch(fail, ne, scratch1, Operand(zero_reg)); - - __ mfc1(scratch0, double_scratch0); - __ SmiTagCheckOverflow(key, scratch0, scratch1); - __ BranchOnOverflow(fail, scratch1); - __ bind(&key_ok); - } else { - // Check that the key is a smi. - __ JumpIfNotSmi(key, fail); - } -} - - void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, ElementsKind elements_kind) { @@ -3432,8 +3388,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key, &miss_force_generic); __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); // a3: elements array @@ -3541,7 +3497,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( CpuFeatures::Scope scope(FPU); __ mtc1(value, f0); __ cvt_d_w(f0, f0); - __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); + __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag)); __ Ret(); } else { Register dst1 = t2; @@ -3589,7 +3545,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ Cvt_d_uw(f0, value, f22); - __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); + __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag)); __ Ret(); } else { @@ -3643,7 +3599,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ AllocateHeapNumber(v0, t3, t5, t6, &slow); // The float (single) value is already in fpu reg f0 (if we use float). __ cvt_d_s(f0, f0); - __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); + __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag)); __ Ret(); } else { // Allocate a HeapNumber for the result. Don't use a0 and a1 as @@ -3771,8 +3727,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key, &miss_force_generic); __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); @@ -4151,8 +4107,9 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(a0, &miss_force_generic, at, USE_DELAY_SLOT); + // The delay slot can be safely used here, a1 is an object pointer. // Get the elements array. __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); @@ -4202,8 +4159,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key_reg, &miss_force_generic); // Get the elements array. __ lw(elements_reg, @@ -4276,8 +4233,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(key_reg, &miss_force_generic); if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { __ JumpIfNotSmi(value_reg, &transition_elements_kind); @@ -4443,9 +4400,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); + __ JumpIfNotSmi(key_reg, &miss_force_generic); __ lw(elements_reg, FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); diff --git a/deps/v8/src/mirror-debugger.js b/deps/v8/src/mirror-debugger.js index c7f0dccb7b..c43dd228ec 100644 --- a/deps/v8/src/mirror-debugger.js +++ b/deps/v8/src/mirror-debugger.js @@ -596,23 +596,6 @@ ObjectMirror.prototype.protoObject = function() { }; -/** - * Return the primitive value if this is object of Boolean, Number or String - * type (but not Date). Otherwise return undefined. - */ -ObjectMirror.prototype.primitiveValue = function() { - if (!IS_STRING_WRAPPER(this.value_) && !IS_NUMBER_WRAPPER(this.value_) && - !IS_BOOLEAN_WRAPPER(this.value_)) { - return void 0; - } - var primitiveValue = %_ValueOf(this.value_); - if (IS_UNDEFINED(primitiveValue)) { - return void 0; - } - return MakeMirror(primitiveValue); -}; - - ObjectMirror.prototype.hasNamedInterceptor = function() { // Get information on interceptors for this object. var x = %GetInterceptorInfo(this.value_); @@ -913,22 +896,6 @@ FunctionMirror.prototype.constructedBy = function(opt_max_instances) { }; -FunctionMirror.prototype.scopeCount = function() { - if (this.resolved()) { - return %GetFunctionScopeCount(this.value()); - } else { - return 0; - } -}; - - -FunctionMirror.prototype.scope = function(index) { - if (this.resolved()) { - return new ScopeMirror(void 0, this, index); - } -}; - - FunctionMirror.prototype.toText = function() { return this.source(); }; @@ -1605,7 +1572,7 @@ FrameMirror.prototype.scopeCount = function() { FrameMirror.prototype.scope = function(index) { - return new ScopeMirror(this, void 0, index); + return new ScopeMirror(this, index); }; @@ -1768,54 +1735,39 @@ FrameMirror.prototype.toText = function(opt_locals) { var kScopeDetailsTypeIndex = 0; var kScopeDetailsObjectIndex = 1; -function ScopeDetails(frame, fun, index) { - if (frame) { - this.break_id_ = frame.break_id_; - this.details_ = %GetScopeDetails(frame.break_id_, - frame.details_.frameId(), - frame.details_.inlinedFrameIndex(), - index); - } else { - this.details_ = %GetFunctionScopeDetails(fun.value(), index); - this.break_id_ = undefined; - } +function ScopeDetails(frame, index) { + this.break_id_ = frame.break_id_; + this.details_ = %GetScopeDetails(frame.break_id_, + frame.details_.frameId(), + frame.details_.inlinedFrameIndex(), + index); } ScopeDetails.prototype.type = function() { - if (!IS_UNDEFINED(this.break_id_)) { - %CheckExecutionState(this.break_id_); - } + %CheckExecutionState(this.break_id_); return this.details_[kScopeDetailsTypeIndex]; }; ScopeDetails.prototype.object = function() { - if (!IS_UNDEFINED(this.break_id_)) { - %CheckExecutionState(this.break_id_); - } + %CheckExecutionState(this.break_id_); return this.details_[kScopeDetailsObjectIndex]; }; /** - * Mirror object for scope of frame or function. Either frame or function must - * be specified. + * Mirror object for scope. * @param {FrameMirror} frame The frame this scope is a part of - * @param {FunctionMirror} function The function this scope is a part of * @param {number} index The scope index in the frame * @constructor * @extends Mirror */ -function ScopeMirror(frame, function, index) { +function ScopeMirror(frame, index) { %_CallFunction(this, SCOPE_TYPE, Mirror); - if (frame) { - this.frame_index_ = frame.index_; - } else { - this.frame_index_ = undefined; - } + this.frame_index_ = frame.index_; this.scope_index_ = index; - this.details_ = new ScopeDetails(frame, function, index); + this.details_ = new ScopeDetails(frame, index); } inherits(ScopeMirror, Mirror); @@ -2282,11 +2234,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, content.protoObject = this.serializeReference(mirror.protoObject()); content.prototypeObject = this.serializeReference(mirror.prototypeObject()); - var primitiveValue = mirror.primitiveValue(); - if (!IS_UNDEFINED(primitiveValue)) { - content.primitiveValue = this.serializeReference(primitiveValue); - } - // Add flags to indicate whether there are interceptors. if (mirror.hasNamedInterceptor()) { content.namedInterceptor = true; @@ -2312,15 +2259,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, serializeLocationFields(mirror.sourceLocation(), content); } - - content.scopes = []; - for (var i = 0; i < mirror.scopeCount(); i++) { - var scope = mirror.scope(i); - content.scopes.push({ - type: scope.scopeType(), - index: i - }); - } } // Add date specific properties. diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc index cd2ccf81c7..8eefb23db2 100644 --- a/deps/v8/src/objects-debug.cc +++ b/deps/v8/src/objects-debug.cc @@ -135,9 +135,6 @@ void HeapObject::HeapObjectVerify() { case JS_CONTEXT_EXTENSION_OBJECT_TYPE: JSObject::cast(this)->JSObjectVerify(); break; - case JS_MODULE_TYPE: - JSModule::cast(this)->JSModuleVerify(); - break; case JS_VALUE_TYPE: JSValue::cast(this)->JSValueVerify(); break; @@ -369,15 +366,6 @@ void FixedDoubleArray::FixedDoubleArrayVerify() { } -void JSModule::JSModuleVerify() { - Object* v = context(); - if (v->IsHeapObject()) { - VerifyHeapPointer(v); - } - CHECK(v->IsUndefined() || v->IsModuleContext()); -} - - void JSValue::JSValueVerify() { Object* v = value(); if (v->IsHeapObject()) { diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 459420c5d3..68feda46b4 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -581,8 +581,7 @@ bool Object::IsContext() { map == heap->catch_context_map() || map == heap->with_context_map() || map == heap->global_context_map() || - map == heap->block_context_map() || - map == heap->module_context_map()); + map == heap->block_context_map()); } return false; } @@ -595,13 +594,6 @@ bool Object::IsGlobalContext() { } -bool Object::IsModuleContext() { - return Object::IsHeapObject() && - HeapObject::cast(this)->map() == - HeapObject::cast(this)->GetHeap()->module_context_map(); -} - - bool Object::IsScopeInfo() { return Object::IsHeapObject() && HeapObject::cast(this)->map() == @@ -621,7 +613,6 @@ TYPE_CHECKER(Code, CODE_TYPE) TYPE_CHECKER(Oddball, ODDBALL_TYPE) TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE) TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE) -TYPE_CHECKER(JSModule, JS_MODULE_TYPE) TYPE_CHECKER(JSValue, JS_VALUE_TYPE) TYPE_CHECKER(JSDate, JS_DATE_TYPE) TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE) @@ -1447,8 +1438,6 @@ int JSObject::GetHeaderSize() { // field operations considerably on average. if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; switch (type) { - case JS_MODULE_TYPE: - return JSModule::kSize; case JS_GLOBAL_PROXY_TYPE: return JSGlobalProxy::kSize; case JS_GLOBAL_OBJECT_TYPE: @@ -1935,15 +1924,15 @@ Object* DescriptorArray::GetValue(int descriptor_number) { } -PropertyDetails DescriptorArray::GetDetails(int descriptor_number) { +Smi* DescriptorArray::GetDetails(int descriptor_number) { ASSERT(descriptor_number < number_of_descriptors()); - Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number)); - return PropertyDetails(Smi::cast(details)); + return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number))); } PropertyType DescriptorArray::GetType(int descriptor_number) { - return GetDetails(descriptor_number).type(); + ASSERT(descriptor_number < number_of_descriptors()); + return PropertyDetails(GetDetails(descriptor_number)).type(); } @@ -2006,10 +1995,15 @@ bool DescriptorArray::IsNullDescriptor(int descriptor_number) { } +bool DescriptorArray::IsDontEnum(int descriptor_number) { + return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum(); +} + + void DescriptorArray::Get(int descriptor_number, Descriptor* desc) { desc->Init(GetKey(descriptor_number), GetValue(descriptor_number), - GetDetails(descriptor_number)); + PropertyDetails(GetDetails(descriptor_number))); } @@ -3012,26 +3006,26 @@ void Code::set_is_pregenerated(bool value) { bool Code::optimizable() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); return READ_BYTE_FIELD(this, kOptimizableOffset) == 1; } void Code::set_optimizable(bool value) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0); } bool Code::has_deoptimization_support() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); return FullCodeFlagsHasDeoptimizationSupportField::decode(flags); } void Code::set_has_deoptimization_support(bool value) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value); WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); @@ -3039,14 +3033,14 @@ void Code::set_has_deoptimization_support(bool value) { bool Code::has_debug_break_slots() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); return FullCodeFlagsHasDebugBreakSlotsField::decode(flags); } void Code::set_has_debug_break_slots(bool value) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value); WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); @@ -3054,41 +3048,56 @@ void Code::set_has_debug_break_slots(bool value) { bool Code::is_compiled_optimizable() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); return FullCodeFlagsIsCompiledOptimizable::decode(flags); } void Code::set_compiled_optimizable(bool value) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value); WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); } +bool Code::has_self_optimization_header() { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + return FullCodeFlagsHasSelfOptimizationHeader::decode(flags); +} + + +void Code::set_self_optimization_header(bool value) { + ASSERT(kind() == FUNCTION); + byte flags = READ_BYTE_FIELD(this, kFullCodeFlags); + flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value); + WRITE_BYTE_FIELD(this, kFullCodeFlags, flags); +} + + int Code::allow_osr_at_loop_nesting_level() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset); } void Code::set_allow_osr_at_loop_nesting_level(int level) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); ASSERT(level >= 0 && level <= kMaxLoopNestingMarker); WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level); } int Code::profiler_ticks() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); return READ_BYTE_FIELD(this, kProfilerTicksOffset); } void Code::set_profiler_ticks(int ticks) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); ASSERT(ticks < 256); WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks); } @@ -3120,13 +3129,13 @@ void Code::set_safepoint_table_offset(unsigned offset) { unsigned Code::stack_check_table_offset() { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset); } void Code::set_stack_check_table_offset(unsigned offset) { - ASSERT_EQ(FUNCTION, kind()); + ASSERT(kind() == FUNCTION); ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize))); WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset); } @@ -4086,16 +4095,6 @@ void Foreign::set_foreign_address(Address value) { } -ACCESSORS(JSModule, context, Object, kContextOffset) - - -JSModule* JSModule::cast(Object* obj) { - ASSERT(obj->IsJSModule()); - ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize); - return reinterpret_cast<JSModule*>(obj); -} - - ACCESSORS(JSValue, value, Object, kValueOffset) diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc index febdaabb12..a12b81388c 100644 --- a/deps/v8/src/objects-printer.cc +++ b/deps/v8/src/objects-printer.cc @@ -135,9 +135,6 @@ void HeapObject::HeapObjectPrint(FILE* out) { case ODDBALL_TYPE: Oddball::cast(this)->to_string()->Print(out); break; - case JS_MODULE_TYPE: - JSModule::cast(this)->JSModulePrint(out); - break; case JS_FUNCTION_TYPE: JSFunction::cast(this)->JSFunctionPrint(out); break; @@ -155,7 +152,7 @@ void HeapObject::HeapObjectPrint(FILE* out) { JSValue::cast(this)->value()->Print(out); break; case JS_DATE_TYPE: - JSDate::cast(this)->JSDatePrint(out); + JSDate::cast(this)->value()->Print(out); break; case CODE_TYPE: Code::cast(this)->CodePrint(out); @@ -442,19 +439,6 @@ void JSObject::JSObjectPrint(FILE* out) { } -void JSModule::JSModulePrint(FILE* out) { - HeapObject::PrintHeader(out, "JSModule"); - PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); - PrintF(out, " - context = "); - context()->Print(out); - PrintElementsKind(out, this->map()->elements_kind()); - PrintF(out, " {\n"); - PrintProperties(out); - PrintElements(out); - PrintF(out, " }\n"); -} - - static const char* TypeToString(InstanceType type) { switch (type) { case INVALID_TYPE: return "INVALID"; @@ -501,7 +485,6 @@ static const char* TypeToString(InstanceType type) { case ODDBALL_TYPE: return "ODDBALL"; case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL"; case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO"; - case JS_MODULE_TYPE: return "JS_MODULE"; case JS_FUNCTION_TYPE: return "JS_FUNCTION"; case CODE_TYPE: return "CODE"; case JS_ARRAY_TYPE: return "JS_ARRAY"; diff --git a/deps/v8/src/objects-visiting-inl.h b/deps/v8/src/objects-visiting-inl.h index 8ba92f70c9..627d1bc2ef 100644 --- a/deps/v8/src/objects-visiting-inl.h +++ b/deps/v8/src/objects-visiting-inl.h @@ -72,7 +72,9 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() { table_.Register(kVisitSeqTwoByteString, &VisitSeqTwoByteString); - table_.Register(kVisitJSFunction, &VisitJSFunction); + table_.Register(kVisitJSFunction, + &JSObjectVisitor:: + template VisitSpecialized<JSFunction::kSize>); table_.Register(kVisitFreeSpace, &VisitFreeSpace); diff --git a/deps/v8/src/objects-visiting.cc b/deps/v8/src/objects-visiting.cc index a2dc43e247..c7c8a87895 100644 --- a/deps/v8/src/objects-visiting.cc +++ b/deps/v8/src/objects-visiting.cc @@ -133,7 +133,6 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId( case JS_OBJECT_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE: - case JS_MODULE_TYPE: case JS_VALUE_TYPE: case JS_DATE_TYPE: case JS_ARRAY_TYPE: diff --git a/deps/v8/src/objects-visiting.h b/deps/v8/src/objects-visiting.h index b476dfef2e..26e79ae5ed 100644 --- a/deps/v8/src/objects-visiting.h +++ b/deps/v8/src/objects-visiting.h @@ -289,23 +289,6 @@ class StaticNewSpaceVisitor : public StaticVisitorBase { } private: - static inline int VisitJSFunction(Map* map, HeapObject* object) { - Heap* heap = map->GetHeap(); - VisitPointers(heap, - HeapObject::RawField(object, JSFunction::kPropertiesOffset), - HeapObject::RawField(object, JSFunction::kCodeEntryOffset)); - - // Don't visit code entry. We are using this visitor only during scavenges. - - VisitPointers( - heap, - HeapObject::RawField(object, - JSFunction::kCodeEntryOffset + kPointerSize), - HeapObject::RawField(object, - JSFunction::kNonWeakFieldsEndOffset)); - return JSFunction::kSize; - } - static inline int VisitByteArray(Map* map, HeapObject* object) { return reinterpret_cast<ByteArray*>(object)->ByteArraySize(); } diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index c3663eba3a..904cf524cb 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -1338,7 +1338,6 @@ void HeapObject::IterateBody(InstanceType type, int object_size, break; case JS_OBJECT_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE: - case JS_MODULE_TYPE: case JS_VALUE_TYPE: case JS_DATE_TYPE: case JS_ARRAY_TYPE: @@ -2322,7 +2321,7 @@ Object* Map::GetDescriptorContents(String* sentinel_name, } // If the transition already exists, return its descriptor. if (index != DescriptorArray::kNotFound) { - PropertyDetails details = descriptors->GetDetails(index); + PropertyDetails details(descriptors->GetDetails(index)); if (details.type() == ELEMENTS_TRANSITION) { return descriptors->GetValue(index); } else { @@ -3026,6 +3025,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( String* name, Object* value, PropertyAttributes attributes) { + // Make sure that the top context does not change when doing callbacks or // interceptor calls. AssertNoContextChange ncc; @@ -3094,6 +3094,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); case HANDLER: UNREACHABLE(); + return value; } UNREACHABLE(); // keep the compiler happy return value; @@ -3344,7 +3345,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, DescriptorArray* descs = map_of_this->instance_descriptors(); for (int i = 0; i < descs->number_of_descriptors(); i++) { - PropertyDetails details = descs->GetDetails(i); + PropertyDetails details(descs->GetDetails(i)); switch (details.type()) { case CONSTANT_FUNCTION: { PropertyDetails d = @@ -3752,11 +3753,13 @@ MaybeObject* JSObject::GetHiddenPropertiesDictionary(bool create_if_absent) { MaybeObject* dict_alloc = StringDictionary::Allocate(kInitialSize); StringDictionary* dictionary; if (!dict_alloc->To<StringDictionary>(&dictionary)) return dict_alloc; - // Using AddProperty or SetPropertyPostInterceptor here could fail, because - // object might be non-extensible. - return HasFastProperties() - ? AddFastProperty(GetHeap()->hidden_symbol(), dictionary, DONT_ENUM) - : AddSlowProperty(GetHeap()->hidden_symbol(), dictionary, DONT_ENUM); + MaybeObject* store_result = + SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), + dictionary, + DONT_ENUM, + kNonStrictMode); + if (store_result->IsFailure()) return store_result; + return dictionary; } @@ -4206,7 +4209,7 @@ int Map::NumberOfDescribedProperties(PropertyAttributes filter) { int result = 0; DescriptorArray* descs = instance_descriptors(); for (int i = 0; i < descs->number_of_descriptors(); i++) { - PropertyDetails details = descs->GetDetails(i); + PropertyDetails details(descs->GetDetails(i)); if (descs->IsProperty(i) && (details.attributes() & filter) == 0) { result++; } @@ -4409,29 +4412,37 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index, } -MaybeObject* JSObject::CreateAccessorPairFor(String* name) { +MaybeObject* JSObject::DefinePropertyAccessor(String* name, + Object* getter, + Object* setter, + PropertyAttributes attributes) { + // Lookup the name. LookupResult result(GetHeap()->isolate()); LocalLookupRealNamedProperty(name, &result); - if (result.IsProperty() && result.type() == CALLBACKS) { - ASSERT(!result.IsDontDelete()); - Object* obj = result.GetCallbackObject(); - if (obj->IsAccessorPair()) { - return AccessorPair::cast(obj)->CopyWithoutTransitions(); + if (result.IsFound()) { + if (result.type() == CALLBACKS) { + ASSERT(!result.IsDontDelete()); + Object* obj = result.GetCallbackObject(); + // Need to preserve old getters/setters. + if (obj->IsAccessorPair()) { + AccessorPair* copy; + { MaybeObject* maybe_copy = + AccessorPair::cast(obj)->CopyWithoutTransitions(); + if (!maybe_copy->To(©)) return maybe_copy; + } + copy->SetComponents(getter, setter); + // Use set to update attributes. + return SetPropertyCallback(name, copy, attributes); + } } } - return GetHeap()->AllocateAccessorPair(); -} - -MaybeObject* JSObject::DefinePropertyAccessor(String* name, - Object* getter, - Object* setter, - PropertyAttributes attributes) { AccessorPair* accessors; - { MaybeObject* maybe_accessors = CreateAccessorPairFor(name); + { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); if (!maybe_accessors->To(&accessors)) return maybe_accessors; } accessors->SetComponents(getter, setter); + return SetPropertyCallback(name, accessors, attributes); } @@ -5687,7 +5698,7 @@ MaybeObject* DescriptorArray::CopyFrom(int dst_index, int src_index, const WhitenessWitness& witness) { Object* value = src->GetValue(src_index); - PropertyDetails details = src->GetDetails(src_index); + PropertyDetails details(src->GetDetails(src_index)); if (details.type() == CALLBACKS && value->IsAccessorPair()) { MaybeObject* maybe_copy = AccessorPair::cast(value)->CopyWithoutTransitions(); @@ -5730,7 +5741,7 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor, if (replacing) { // We are replacing an existing descriptor. We keep the enumeration // index of a visible property. - PropertyType t = GetDetails(index).type(); + PropertyType t = PropertyDetails(GetDetails(index)).type(); if (t == CONSTANT_FUNCTION || t == FIELD || t == CALLBACKS || @@ -5757,7 +5768,8 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor, int enumeration_index = NextEnumerationIndex(); if (!descriptor->ContainsTransition()) { if (keep_enumeration_index) { - descriptor->SetEnumerationIndex(GetDetails(index).index()); + descriptor->SetEnumerationIndex( + PropertyDetails(GetDetails(index)).index()); } else { descriptor->SetEnumerationIndex(enumeration_index); ++enumeration_index; @@ -5901,10 +5913,10 @@ int DescriptorArray::BinarySearch(String* name, int low, int high) { ASSERT(hash == mid_hash); // There might be more, so we find the first one and // check them all to see if we have a match. - if (name == mid_name && !IsNullDescriptor(mid)) return mid; + if (name == mid_name && !is_null_descriptor(mid)) return mid; while ((mid > low) && (GetKey(mid - 1)->Hash() == hash)) mid--; for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) { - if (GetKey(mid)->Equals(name) && !IsNullDescriptor(mid)) return mid; + if (GetKey(mid)->Equals(name) && !is_null_descriptor(mid)) return mid; } break; } @@ -5918,7 +5930,7 @@ int DescriptorArray::LinearSearch(String* name, int len) { String* entry = GetKey(number); if ((entry->Hash() == hash) && name->Equals(entry) && - !IsNullDescriptor(number)) { + !is_null_descriptor(number)) { return number; } } @@ -8374,10 +8386,6 @@ void Code::Disassemble(const char* name, FILE* out) { if (is_call_stub() || is_keyed_call_stub()) { PrintF(out, "argc = %d\n", arguments_count()); } - if (is_compare_ic_stub()) { - CompareIC::State state = CompareIC::ComputeState(this); - PrintF(out, "compare_state = %s\n", CompareIC::GetStateName(state)); - } } if ((name != NULL) && (name[0] != '\0')) { PrintF(out, "name = %s\n", name); diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 80d1fd47d0..ccd07ff1d7 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -59,7 +59,6 @@ // - JSWeakMap // - JSRegExp // - JSFunction -// - JSModule // - GlobalObject // - JSGlobalObject // - JSBuiltinsObject @@ -307,7 +306,6 @@ const int kVariableSizeSentinel = 0; V(JS_DATE_TYPE) \ V(JS_OBJECT_TYPE) \ V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ - V(JS_MODULE_TYPE) \ V(JS_GLOBAL_OBJECT_TYPE) \ V(JS_BUILTINS_OBJECT_TYPE) \ V(JS_GLOBAL_PROXY_TYPE) \ @@ -628,7 +626,6 @@ enum InstanceType { JS_DATE_TYPE, JS_OBJECT_TYPE, JS_CONTEXT_EXTENSION_OBJECT_TYPE, - JS_MODULE_TYPE, JS_GLOBAL_OBJECT_TYPE, JS_BUILTINS_OBJECT_TYPE, JS_GLOBAL_PROXY_TYPE, @@ -680,7 +677,6 @@ const int kExternalArrayTypeCount = STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType); STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType); -STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType); STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType); @@ -807,7 +803,6 @@ class MaybeObject BASE_EMBEDDED { V(JSReceiver) \ V(JSObject) \ V(JSContextExtensionObject) \ - V(JSModule) \ V(Map) \ V(DescriptorArray) \ V(DeoptimizationInputData) \ @@ -817,7 +812,6 @@ class MaybeObject BASE_EMBEDDED { V(FixedDoubleArray) \ V(Context) \ V(GlobalContext) \ - V(ModuleContext) \ V(ScopeInfo) \ V(JSFunction) \ V(Code) \ @@ -2192,7 +2186,6 @@ class JSObject: public JSReceiver { Object* getter, Object* setter, PropertyAttributes attributes); - MUST_USE_RESULT MaybeObject* CreateAccessorPairFor(String* name); MUST_USE_RESULT MaybeObject* DefinePropertyAccessor( String* name, Object* getter, @@ -2474,7 +2467,7 @@ class DescriptorArray: public FixedArray { // Accessors for fetching instance descriptor at descriptor number. inline String* GetKey(int descriptor_number); inline Object* GetValue(int descriptor_number); - inline PropertyDetails GetDetails(int descriptor_number); + inline Smi* GetDetails(int descriptor_number); inline PropertyType GetType(int descriptor_number); inline int GetFieldIndex(int descriptor_number); inline JSFunction* GetConstantFunction(int descriptor_number); @@ -2483,6 +2476,7 @@ class DescriptorArray: public FixedArray { inline bool IsProperty(int descriptor_number); inline bool IsTransitionOnly(int descriptor_number); inline bool IsNullDescriptor(int descriptor_number); + inline bool IsDontEnum(int descriptor_number); class WhitenessWitness { public: @@ -2636,6 +2630,10 @@ class DescriptorArray: public FixedArray { return descriptor_number << 1; } + bool is_null_descriptor(int descriptor_number) { + return PropertyDetails(GetDetails(descriptor_number)).type() == + NULL_DESCRIPTOR; + } // Swap operation on FixedArray without using write barriers. static inline void NoIncrementalWriteBarrierSwap( FixedArray* array, int first, int second); @@ -3415,8 +3413,8 @@ class ScopeInfo : public FixedArray { // otherwise returns a value < 0. The name must be a symbol (canonicalized). int ParameterIndex(String* name); - // Lookup support for serialized scope info. Returns the function context - // slot index if the function name is present and context-allocated (named + // Lookup support for serialized scope info. Returns the + // function context slot index if the function name is present (named // function expressions, only), otherwise returns a value < 0. The name // must be a symbol (canonicalized). int FunctionContextSlotIndex(String* name, VariableMode* mode); @@ -4245,6 +4243,11 @@ class Code: public HeapObject { inline bool is_compiled_optimizable(); inline void set_compiled_optimizable(bool value); + // [has_self_optimization_header]: For FUNCTION kind, tells if it has + // a self-optimization header. + inline bool has_self_optimization_header(); + inline void set_self_optimization_header(bool value); + // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for // how long the function has been marked for OSR and therefore which // level of loop nesting we are willing to do on-stack replacement @@ -4471,6 +4474,7 @@ class Code: public HeapObject { public BitField<bool, 0, 1> {}; // NOLINT class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {}; class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {}; + class FullCodeFlagsHasSelfOptimizationHeader: public BitField<bool, 3, 1> {}; static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; @@ -5692,35 +5696,6 @@ class SharedFunctionInfo: public HeapObject { }; -// Representation for module instance objects. -class JSModule: public JSObject { - public: - // [context]: the context holding the module's locals, or undefined if none. - DECL_ACCESSORS(context, Object) - - // Casting. - static inline JSModule* cast(Object* obj); - - // Dispatched behavior. -#ifdef OBJECT_PRINT - inline void JSModulePrint() { - JSModulePrint(stdout); - } - void JSModulePrint(FILE* out); -#endif -#ifdef DEBUG - void JSModuleVerify(); -#endif - - // Layout description. - static const int kContextOffset = JSObject::kHeaderSize; - static const int kSize = kContextOffset + kPointerSize; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(JSModule); -}; - - // JSFunction describes JavaScript functions. class JSFunction: public JSObject { public: @@ -7637,10 +7612,6 @@ class Oddball: public HeapObject { kToNumberOffset + kPointerSize, kSize> BodyDescriptor; - STATIC_CHECK(kKindOffset == Internals::kOddballKindOffset); - STATIC_CHECK(kNull == Internals::kNullOddballKind); - STATIC_CHECK(kUndefined == Internals::kUndefinedOddballKind); - private: DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); }; diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc index 862051956b..da680411a9 100644 --- a/deps/v8/src/parser.cc +++ b/deps/v8/src/parser.cc @@ -1333,19 +1333,11 @@ Module* Parser::ParseModuleLiteral(bool* ok) { Expect(Token::RBRACE, CHECK_OK); scope->set_end_position(scanner().location().end_pos); - body->set_scope(scope); + body->set_block_scope(scope); - // Instance objects have to be created ahead of time (before code generation - // linking them) because of potentially cyclic references between them. - // We create them here, to avoid another pass over the AST. - Interface* interface = scope->interface(); - interface->MakeModule(ok); + scope->interface()->Freeze(ok); ASSERT(ok); - interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok); - ASSERT(ok); - interface->Freeze(ok); - ASSERT(ok); - return factory()->NewModuleLiteral(body, interface); + return factory()->NewModuleLiteral(body, scope->interface()); } @@ -1411,14 +1403,7 @@ Module* Parser::ParseModuleUrl(bool* ok) { #ifdef DEBUG if (FLAG_print_interface_details) PrintF("# Url "); #endif - - Module* result = factory()->NewModuleUrl(symbol); - Interface* interface = result->interface(); - interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok); - ASSERT(ok); - interface->Freeze(ok); - ASSERT(ok); - return result; + return factory()->NewModuleUrl(symbol); } @@ -2030,7 +2015,7 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { Expect(Token::RBRACE, CHECK_OK); block_scope->set_end_position(scanner().location().end_pos); block_scope = block_scope->FinalizeBlockScope(); - body->set_scope(block_scope); + body->set_block_scope(block_scope); return body; } @@ -2269,7 +2254,7 @@ Block* Parser::ParseVariableDeclarations( // Global variable declarations must be compiled in a specific // way. When the script containing the global variable declaration // is entered, the global variable must be declared, so that if it - // doesn't exist (on the global object itself, see ES5 errata) it + // doesn't exist (not even in a prototype of the global object) it // gets created with an initial undefined value. This is handled // by the declarations part of the function representing the // top-level global code; see Runtime::DeclareGlobalVariable. If @@ -2932,7 +2917,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { top_scope_ = saved_scope; for_scope->set_end_position(scanner().location().end_pos); for_scope = for_scope->FinalizeBlockScope(); - body_block->set_scope(for_scope); + body_block->set_block_scope(for_scope); // Parsed for-in loop w/ let declaration. return loop; @@ -3012,7 +2997,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { Block* result = factory()->NewBlock(NULL, 2, false); result->AddStatement(init); result->AddStatement(loop); - result->set_scope(for_scope); + result->set_block_scope(for_scope); if (loop) loop->Initialize(NULL, cond, next, body); return result; } else { @@ -4475,15 +4460,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, Variable* fvar = NULL; Token::Value fvar_init_op = Token::INIT_CONST; if (type == FunctionLiteral::NAMED_EXPRESSION) { - if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; - VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; - fvar = new(zone()) Variable(top_scope_, - function_name, fvar_mode, true /* is valid LHS */, - Variable::NORMAL, kCreatedInitialized); - VariableProxy* proxy = factory()->NewVariableProxy(fvar); - VariableDeclaration* fvar_declaration = - factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_); - top_scope_->DeclareFunctionVar(fvar_declaration); + VariableMode fvar_mode; + if (is_extended_mode()) { + fvar_mode = CONST_HARMONY; + fvar_init_op = Token::INIT_CONST_HARMONY; + } else { + fvar_mode = CONST; + } + fvar = + top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory()); } // Determine whether the function will be lazily compiled. diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc index 089ea38d9a..dd7253ba06 100644 --- a/deps/v8/src/platform-cygwin.cc +++ b/deps/v8/src/platform-cygwin.cc @@ -62,8 +62,22 @@ double ceiling(double x) { static Mutex* limit_mutex = NULL; +void OS::SetUp() { + // Seed the random number generator. + // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that + // call this setup code within the same millisecond. + uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} + + void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } uint64_t OS::CpuFeaturesImpliedByPlatform() { @@ -620,11 +634,8 @@ class SamplerThread : public Thread { : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { instance_ = new SamplerThread(sampler->interval()); @@ -635,7 +646,7 @@ class SamplerThread : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -721,7 +732,7 @@ class SamplerThread : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SamplerThread* instance_; private: @@ -729,29 +740,10 @@ class SamplerThread : public Thread { }; -Mutex* SamplerThread::mutex_ = NULL; +LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER; SamplerThread* SamplerThread::instance_ = NULL; -void OS::SetUp() { - // Seed the random number generator. - // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that - // call this setup code within the same millisecond. - uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SamplerThread::SetUp(); -} - - -void OS::TearDown() { - SamplerThread::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc index 4a6845ef39..6a004ea7fa 100644 --- a/deps/v8/src/platform-freebsd.cc +++ b/deps/v8/src/platform-freebsd.cc @@ -80,8 +80,22 @@ double ceiling(double x) { static Mutex* limit_mutex = NULL; +void OS::SetUp() { + // Seed the random number generator. + // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that + // call this setup code within the same millisecond. + uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} + + void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } @@ -716,11 +730,8 @@ class SignalSender : public Thread { : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { // Install a signal handler. @@ -740,7 +751,7 @@ class SignalSender : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -833,7 +844,7 @@ class SignalSender : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SignalSender* instance_; static bool signal_handler_installed_; static struct sigaction old_signal_handler_; @@ -842,31 +853,12 @@ class SignalSender : public Thread { DISALLOW_COPY_AND_ASSIGN(SignalSender); }; -Mutex* SignalSender::mutex_ = NULL; +LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER; SignalSender* SignalSender::instance_ = NULL; struct sigaction SignalSender::old_signal_handler_; bool SignalSender::signal_handler_installed_ = false; -void OS::SetUp() { - // Seed the random number generator. - // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that - // call this setup code within the same millisecond. - uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SignalSender::SetUp(); -} - - -void OS::TearDown() { - SignalSender::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc index f6db423e42..9781407e17 100644 --- a/deps/v8/src/platform-linux.cc +++ b/deps/v8/src/platform-linux.cc @@ -46,9 +46,9 @@ #include <sys/stat.h> // open #include <fcntl.h> // open #include <unistd.h> // sysconf -#if defined(__GLIBC__) && !defined(__UCLIBC__) +#ifdef __GLIBC__ #include <execinfo.h> // backtrace, backtrace_symbols -#endif // defined(__GLIBC__) && !defined(__UCLIBC__) +#endif // def __GLIBC__ #include <strings.h> // index #include <errno.h> #include <stdarg.h> @@ -79,8 +79,37 @@ double ceiling(double x) { static Mutex* limit_mutex = NULL; +void OS::SetUp() { + // Seed the random number generator. We preserve microsecond resolution. + uint64_t seed = Ticks() ^ (getpid() << 16); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); + +#ifdef __arm__ + // When running on ARM hardware check that the EABI used by V8 and + // by the C code is the same. + bool hard_float = OS::ArmUsingHardFloat(); + if (hard_float) { +#if !USE_EABI_HARDFLOAT + PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " + "-DUSE_EABI_HARDFLOAT\n"); + exit(1); +#endif + } else { +#if USE_EABI_HARDFLOAT + PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with " + "-DUSE_EABI_HARDFLOAT\n"); + exit(1); +#endif + } +#endif +} + + void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } @@ -535,7 +564,7 @@ void OS::SignalCodeMovingGC() { int OS::StackWalk(Vector<OS::StackFrame> frames) { // backtrace is a glibc extension. -#if defined(__GLIBC__) && !defined(__UCLIBC__) +#ifdef __GLIBC__ int frames_size = frames.length(); ScopedVector<void*> addresses(frames_size); @@ -560,9 +589,9 @@ int OS::StackWalk(Vector<OS::StackFrame> frames) { free(symbols); return frames_count; -#else // defined(__GLIBC__) && !defined(__UCLIBC__) +#else // ndef __GLIBC__ return 0; -#endif // defined(__GLIBC__) && !defined(__UCLIBC__) +#endif // ndef __GLIBC__ } @@ -1074,9 +1103,6 @@ class SignalSender : public Thread { vm_tgid_(getpid()), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void InstallSignalHandler() { struct sigaction sa; sa.sa_sigaction = ProfilerSignalHandler; @@ -1094,7 +1120,7 @@ class SignalSender : public Thread { } static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { // Start a thread that will send SIGPROF signal to VM threads, @@ -1107,7 +1133,7 @@ class SignalSender : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -1210,7 +1236,7 @@ class SignalSender : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SignalSender* instance_; static bool signal_handler_installed_; static struct sigaction old_signal_handler_; @@ -1220,46 +1246,12 @@ class SignalSender : public Thread { }; -Mutex* SignalSender::mutex_ = NULL; +LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER; SignalSender* SignalSender::instance_ = NULL; struct sigaction SignalSender::old_signal_handler_; bool SignalSender::signal_handler_installed_ = false; -void OS::SetUp() { - // Seed the random number generator. We preserve microsecond resolution. - uint64_t seed = Ticks() ^ (getpid() << 16); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - -#ifdef __arm__ - // When running on ARM hardware check that the EABI used by V8 and - // by the C code is the same. - bool hard_float = OS::ArmUsingHardFloat(); - if (hard_float) { -#if !USE_EABI_HARDFLOAT - PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without " - "-DUSE_EABI_HARDFLOAT\n"); - exit(1); -#endif - } else { -#if USE_EABI_HARDFLOAT - PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with " - "-DUSE_EABI_HARDFLOAT\n"); - exit(1); -#endif - } -#endif - SignalSender::SetUp(); -} - - -void OS::TearDown() { - SignalSender::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc index a937ed3a5c..dbcd80e9f2 100644 --- a/deps/v8/src/platform-macos.cc +++ b/deps/v8/src/platform-macos.cc @@ -94,8 +94,18 @@ double ceiling(double x) { static Mutex* limit_mutex = NULL; +void OS::SetUp() { + // Seed the random number generator. We preserve microsecond resolution. + uint64_t seed = Ticks() ^ (getpid() << 16); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} + + void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } @@ -743,11 +753,8 @@ class SamplerThread : public Thread { : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { instance_ = new SamplerThread(sampler->interval()); @@ -758,7 +765,7 @@ class SamplerThread : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -855,7 +862,7 @@ class SamplerThread : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SamplerThread* instance_; private: @@ -865,25 +872,10 @@ class SamplerThread : public Thread { #undef REGISTER_FIELD -Mutex* SamplerThread::mutex_ = NULL; +LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER; SamplerThread* SamplerThread::instance_ = NULL; -void OS::SetUp() { - // Seed the random number generator. We preserve microsecond resolution. - uint64_t seed = Ticks() ^ (getpid() << 16); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SamplerThread::SetUp(); -} - - -void OS::TearDown() { - SamplerThread::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-nullos.cc b/deps/v8/src/platform-nullos.cc index 679ef8e89e..42799dbe7a 100644 --- a/deps/v8/src/platform-nullos.cc +++ b/deps/v8/src/platform-nullos.cc @@ -91,11 +91,6 @@ void OS::PostSetUp() { } -void OS::TearDown() { - UNIMPLEMENTED(); -} - - // Returns the accumulated user time for thread. int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { UNIMPLEMENTED(); diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc index ba33a8444e..6a06e3e536 100644 --- a/deps/v8/src/platform-openbsd.cc +++ b/deps/v8/src/platform-openbsd.cc @@ -100,8 +100,18 @@ static void* GetRandomMmapAddr() { } +void OS::SetUp() { + // Seed the random number generator. We preserve microsecond resolution. + uint64_t seed = Ticks() ^ (getpid() << 16); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} + + void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } @@ -793,9 +803,6 @@ class SignalSender : public Thread { vm_tgid_(getpid()), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void InstallSignalHandler() { struct sigaction sa; sa.sa_sigaction = ProfilerSignalHandler; @@ -813,7 +820,7 @@ class SignalSender : public Thread { } static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { // Start a thread that will send SIGPROF signal to VM threads, @@ -826,7 +833,7 @@ class SignalSender : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -920,7 +927,7 @@ class SignalSender : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SignalSender* instance_; static bool signal_handler_installed_; static struct sigaction old_signal_handler_; @@ -930,27 +937,12 @@ class SignalSender : public Thread { }; -Mutex* SignalSender::mutex_ = NULL; +LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER; SignalSender* SignalSender::instance_ = NULL; struct sigaction SignalSender::old_signal_handler_; bool SignalSender::signal_handler_installed_ = false; -void OS::SetUp() { - // Seed the random number generator. We preserve microsecond resolution. - uint64_t seed = Ticks() ^ (getpid() << 16); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SignalSender::SetUp(); -} - - -void OS::TearDown() { - SignalSender::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc index 66316594c8..59066ea39e 100644 --- a/deps/v8/src/platform-posix.cc +++ b/deps/v8/src/platform-posix.cc @@ -147,6 +147,15 @@ UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction()) #undef MATH_FUNCTION +void MathSetup() { + init_fast_sin_function(); + init_fast_cos_function(); + init_fast_tan_function(); + init_fast_log_function(); + init_fast_sqrt_function(); +} + + double OS::nan_value() { // NAN from math.h is defined in C99 and not in POSIX. return NAN; @@ -304,11 +313,20 @@ int OS::VSNPrintF(Vector<char> str, #if defined(V8_TARGET_ARCH_IA32) static OS::MemCopyFunction memcopy_function = NULL; +static LazyMutex memcopy_function_mutex = LAZY_MUTEX_INITIALIZER; // Defined in codegen-ia32.cc. OS::MemCopyFunction CreateMemCopyFunction(); // Copy memory area to disjoint memory area. void OS::MemCopy(void* dest, const void* src, size_t size) { + if (memcopy_function == NULL) { + ScopedLock lock(memcopy_function_mutex.Pointer()); + if (memcopy_function == NULL) { + OS::MemCopyFunction temp = CreateMemCopyFunction(); + MemoryBarrier(); + memcopy_function = temp; + } + } // Note: here we rely on dependent reads being ordered. This is true // on all architectures we currently support. (*memcopy_function)(dest, src, size); @@ -318,18 +336,6 @@ void OS::MemCopy(void* dest, const void* src, size_t size) { } #endif // V8_TARGET_ARCH_IA32 - -void POSIXPostSetUp() { -#if defined(V8_TARGET_ARCH_IA32) - memcopy_function = CreateMemCopyFunction(); -#endif - init_fast_sin_function(); - init_fast_cos_function(); - init_fast_tan_function(); - init_fast_log_function(); - init_fast_sqrt_function(); -} - // ---------------------------------------------------------------------------- // POSIX string support. // diff --git a/deps/v8/src/platform-posix.h b/deps/v8/src/platform-posix.h index 7a982ed2ef..4ae0e526fb 100644 --- a/deps/v8/src/platform-posix.h +++ b/deps/v8/src/platform-posix.h @@ -31,8 +31,9 @@ namespace v8 { namespace internal { -// Used by platform implementation files during OS::PostSetUp(). -void POSIXPostSetUp(); +// Used by platform implementation files during OS::PostSetUp() to initialize +// the math functions. +void MathSetup(); } } // namespace v8::internal diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc index 4248ea214f..e044dbccad 100644 --- a/deps/v8/src/platform-solaris.cc +++ b/deps/v8/src/platform-solaris.cc @@ -91,10 +91,22 @@ double ceiling(double x) { static Mutex* limit_mutex = NULL; +void OS::SetUp() { + // Seed the random number generator. + // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly will cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that + // call this setup code within the same millisecond. + uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); + srandom(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} void OS::PostSetUp() { - POSIXPostSetUp(); + // Math functions depend on CPU features therefore they are initialized after + // CPU. + MathSetup(); } @@ -487,10 +499,12 @@ void Thread::set_name(const char* name) { void Thread::Start() { + pthread_attr_t* attr_ptr = NULL; pthread_attr_t attr; if (stack_size_ > 0) { pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_)); + attr_ptr = &attr; } pthread_create(&data_->thread_, NULL, ThreadEntry, this); ASSERT(data_->thread_ != kNoThread); @@ -710,9 +724,6 @@ class SignalSender : public Thread { : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void InstallSignalHandler() { struct sigaction sa; sa.sa_sigaction = ProfilerSignalHandler; @@ -730,7 +741,7 @@ class SignalSender : public Thread { } static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { // Start a thread that will send SIGPROF signal to VM threads, @@ -743,7 +754,7 @@ class SignalSender : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -837,7 +848,7 @@ class SignalSender : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SignalSender* instance_; static bool signal_handler_installed_; static struct sigaction old_signal_handler_; @@ -846,31 +857,12 @@ class SignalSender : public Thread { DISALLOW_COPY_AND_ASSIGN(SignalSender); }; -Mutex* SignalSender::mutex_ = NULL; +LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER; SignalSender* SignalSender::instance_ = NULL; struct sigaction SignalSender::old_signal_handler_; bool SignalSender::signal_handler_installed_ = false; -void OS::SetUp() { - // Seed the random number generator. - // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly will cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that - // call this setup code within the same millisecond. - uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); - srandom(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SignalSender::SetUp(); -} - - -void OS::TearDown() { - SignalSender::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc index 9e377a1977..c79f44217a 100644 --- a/deps/v8/src/platform-win32.cc +++ b/deps/v8/src/platform-win32.cc @@ -51,22 +51,6 @@ int strncasecmp(const char* s1, const char* s2, int n) { // the Microsoft Visual Studio C++ CRT. #ifdef __MINGW32__ - -#ifndef __MINGW64_VERSION_MAJOR - -#define _TRUNCATE 0 -#define STRUNCATE 80 - -inline void MemoryBarrier() { - int barrier = 0; - __asm__ __volatile__("xchgl %%eax,%0 ":"=r" (barrier)); -} - -#endif // __MINGW64_VERSION_MAJOR - - -#ifndef MINGW_HAS_SECURE_API - int localtime_s(tm* out_tm, const time_t* time) { tm* posix_local_time_struct = localtime(time); if (posix_local_time_struct == NULL) return 1; @@ -80,6 +64,21 @@ int fopen_s(FILE** pFile, const char* filename, const char* mode) { return *pFile != NULL ? 0 : 1; } + +#ifndef __MINGW64_VERSION_MAJOR + +// Not sure this the correct interpretation of _mkgmtime +time_t _mkgmtime(tm* timeptr) { + return mktime(timeptr); +} + + +#define _TRUNCATE 0 +#define STRUNCATE 80 + +#endif // __MINGW64_VERSION_MAJOR + + int _vsnprintf_s(char* buffer, size_t sizeOfBuffer, size_t count, const char* format, va_list argptr) { ASSERT(count == _TRUNCATE); @@ -113,7 +112,16 @@ int strncpy_s(char* dest, size_t dest_size, const char* source, size_t count) { return 0; } -#endif // MINGW_HAS_SECURE_API + +#ifndef __MINGW64_VERSION_MAJOR + +inline void MemoryBarrier() { + int barrier = 0; + __asm__ __volatile__("xchgl %%eax,%0 ":"=r" (barrier)); +} + +#endif // __MINGW64_VERSION_MAJOR + #endif // __MINGW32__ @@ -141,11 +149,20 @@ static Mutex* limit_mutex = NULL; #if defined(V8_TARGET_ARCH_IA32) static OS::MemCopyFunction memcopy_function = NULL; +static LazyMutex memcopy_function_mutex = LAZY_MUTEX_INITIALIZER; // Defined in codegen-ia32.cc. OS::MemCopyFunction CreateMemCopyFunction(); // Copy memory area to disjoint memory area. void OS::MemCopy(void* dest, const void* src, size_t size) { + if (memcopy_function == NULL) { + ScopedLock lock(memcopy_function_mutex.Pointer()); + if (memcopy_function == NULL) { + OS::MemCopyFunction temp = CreateMemCopyFunction(); + MemoryBarrier(); + memcopy_function = temp; + } + } // Note: here we rely on dependent reads being ordered. This is true // on all architectures we currently support. (*memcopy_function)(dest, src, size); @@ -460,9 +477,6 @@ void Time::SetToCurrentTime() { // Check if we need to resync due to elapsed time. needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime; - // Check if we need to resync due to backwards time change. - needs_resync |= time_now.t_ < init_time.t_; - // Resync the clock if necessary. if (needs_resync) { GetSystemTimeAsFileTime(&init_time.ft_); @@ -504,14 +518,11 @@ int64_t Time::LocalOffset() { // Convert to local time, as struct with fields for day, hour, year, etc. tm posix_local_time_struct; if (localtime_s(&posix_local_time_struct, &posix_time)) return 0; + // Convert local time in struct to POSIX time as if it were a UTC time. + time_t local_posix_time = _mkgmtime(&posix_local_time_struct); + Time localtime(1000.0 * local_posix_time); - if (posix_local_time_struct.tm_isdst > 0) { - return (tzinfo_.Bias + tzinfo_.DaylightBias) * -kMsPerMinute; - } else if (posix_local_time_struct.tm_isdst == 0) { - return (tzinfo_.Bias + tzinfo_.StandardBias) * -kMsPerMinute; - } else { - return tzinfo_.Bias * -kMsPerMinute; - } + return localtime.Diff(&rounded_to_second); } @@ -554,13 +565,22 @@ char* Time::LocalTimezone() { } +void OS::SetUp() { + // Seed the random number generator. + // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that + // call this setup code within the same millisecond. + uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); + srand(static_cast<unsigned int>(seed)); + limit_mutex = CreateMutex(); +} + + void OS::PostSetUp() { // Math functions depend on CPU features therefore they are initialized after // CPU. MathSetup(); -#if defined(V8_TARGET_ARCH_IA32) - memcopy_function = CreateMemCopyFunction(); -#endif } @@ -1949,11 +1969,8 @@ class SamplerThread : public Thread { : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } - static void TearDown() { delete mutex_; } - static void AddActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::AddActiveSampler(sampler); if (instance_ == NULL) { instance_ = new SamplerThread(sampler->interval()); @@ -1964,7 +1981,7 @@ class SamplerThread : public Thread { } static void RemoveActiveSampler(Sampler* sampler) { - ScopedLock lock(mutex_); + ScopedLock lock(mutex_.Pointer()); SamplerRegistry::RemoveActiveSampler(sampler); if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); @@ -2050,7 +2067,7 @@ class SamplerThread : public Thread { RuntimeProfilerRateLimiter rate_limiter_; // Protects the process wide state below. - static Mutex* mutex_; + static LazyMutex mutex_; static SamplerThread* instance_; private: @@ -2058,29 +2075,10 @@ class SamplerThread : public Thread { }; -Mutex* SamplerThread::mutex_ = NULL; +LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER; SamplerThread* SamplerThread::instance_ = NULL; -void OS::SetUp() { - // Seed the random number generator. - // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that - // call this setup code within the same millisecond. - uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); - srand(static_cast<unsigned int>(seed)); - limit_mutex = CreateMutex(); - SamplerThread::SetUp(); -} - - -void OS::TearDown() { - SamplerThread::TearDown(); - delete limit_mutex; -} - - Sampler::Sampler(Isolate* isolate, int interval) : isolate_(isolate), interval_(interval), diff --git a/deps/v8/src/platform.h b/deps/v8/src/platform.h index 168791a0a4..3b2aa3c8ba 100644 --- a/deps/v8/src/platform.h +++ b/deps/v8/src/platform.h @@ -123,9 +123,6 @@ class OS { // called after CPU initialization. static void PostSetUp(); - // Clean up platform-OS-related things. Called once at VM shutdown. - static void TearDown(); - // Returns the accumulated user time for thread. This routine // can be used for profiling. The implementation should // strive for high-precision timer resolution, preferable diff --git a/deps/v8/src/preparser.cc b/deps/v8/src/preparser.cc index 0c17eecd6a..20d3b9c59c 100644 --- a/deps/v8/src/preparser.cc +++ b/deps/v8/src/preparser.cc @@ -581,8 +581,9 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) { ParseExpression(true, CHECK_OK); Expect(i::Token::RPAREN, CHECK_OK); - Scope::InsideWith iw(scope_); + scope_->EnterWith(); ParseStatement(CHECK_OK); + scope_->LeaveWith(); return Statement::Default(); } @@ -748,9 +749,10 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) { return Statement::Default(); } Expect(i::Token::RPAREN, CHECK_OK); - { Scope::InsideWith iw(scope_); - ParseBlock(CHECK_OK); - } + scope_->EnterWith(); + ParseBlock(ok); + scope_->LeaveWith(); + if (!*ok) Statement::Default(); catch_or_finally_seen = true; } if (peek() == i::Token::FINALLY) { diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h index 13261f7a5b..f3a43475df 100644 --- a/deps/v8/src/preparser.h +++ b/deps/v8/src/preparser.h @@ -470,19 +470,8 @@ class PreParser { void set_language_mode(i::LanguageMode language_mode) { language_mode_ = language_mode; } - - class InsideWith { - public: - explicit InsideWith(Scope* scope) : scope_(scope) { - scope->with_nesting_count_++; - } - - ~InsideWith() { scope_->with_nesting_count_--; } - - private: - Scope* scope_; - DISALLOW_COPY_AND_ASSIGN(InsideWith); - }; + void EnterWith() { with_nesting_count_++; } + void LeaveWith() { with_nesting_count_--; } private: Scope** const variable_; diff --git a/deps/v8/src/profile-generator-inl.h b/deps/v8/src/profile-generator-inl.h index 284e2dfa36..65369befdf 100644 --- a/deps/v8/src/profile-generator-inl.h +++ b/deps/v8/src/profile-generator-inl.h @@ -95,12 +95,6 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { } -HeapEntry* HeapGraphEdge::from() const { - return const_cast<HeapEntry*>( - reinterpret_cast<const HeapEntry*>(this - child_index_) - 1); -} - - SnapshotObjectId HeapObjectsMap::GetNthGcSubrootId(int delta) { return kGcRootsFirstSubrootId + delta * kObjectIdStep; } diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc index c91e83bb78..2d0984ecbf 100644 --- a/deps/v8/src/profile-generator.cc +++ b/deps/v8/src/profile-generator.cc @@ -34,7 +34,6 @@ #include "scopeinfo.h" #include "unicode.h" #include "zone-inl.h" -#include "debug.h" namespace v8 { namespace internal { @@ -958,6 +957,11 @@ void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) { } +HeapEntry* HeapGraphEdge::From() { + return reinterpret_cast<HeapEntry*>(this - child_index_) - 1; +} + + void HeapEntry::Init(HeapSnapshot* snapshot, Type type, const char* name, @@ -968,11 +972,9 @@ void HeapEntry::Init(HeapSnapshot* snapshot, snapshot_ = snapshot; type_ = type; painted_ = false; - user_reachable_ = false; name_ = name; self_size_ = self_size; retained_size_ = 0; - entry_index_ = -1; children_count_ = children_count; retainers_count_ = retainers_count; dominator_ = NULL; @@ -1106,7 +1108,7 @@ template <size_t ptr_size> struct SnapshotSizeConstants; template <> struct SnapshotSizeConstants<4> { static const int kExpectedHeapGraphEdgeSize = 12; - static const int kExpectedHeapEntrySize = 36; + static const int kExpectedHeapEntrySize = 32; static const size_t kMaxSerializableSnapshotRawSize = 256 * MB; }; @@ -1131,8 +1133,7 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, gc_roots_entry_(NULL), natives_root_entry_(NULL), raw_entries_(NULL), - number_of_edges_(0), - max_snapshot_js_object_id_(0) { + entries_sorted_(false) { STATIC_CHECK( sizeof(HeapGraphEdge) == SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); @@ -1156,16 +1157,10 @@ void HeapSnapshot::Delete() { } -void HeapSnapshot::RememberLastJSObjectId() { - max_snapshot_js_object_id_ = collection_->last_assigned_id(); -} - - void HeapSnapshot::AllocateEntries(int entries_count, int children_count, int retainers_count) { ASSERT(raw_entries_ == NULL); - number_of_edges_ = children_count; raw_entries_size_ = HeapEntry::EntriesSize(entries_count, children_count, retainers_count); raw_entries_ = NewArray<char>(raw_entries_size_); @@ -1184,7 +1179,6 @@ void HeapSnapshot::ClearPaint() { HeapEntry* HeapSnapshot::AddRootEntry(int children_count) { ASSERT(root_entry_ == NULL); - ASSERT(entries_.is_empty()); // Root entry must be the first one. return (root_entry_ = AddEntry(HeapEntry::kObject, "", HeapObjectsMap::kInternalRootObjectId, @@ -1255,25 +1249,24 @@ HeapEntry* HeapSnapshot::GetNextEntryToInit() { } -class FindEntryById { - public: - explicit FindEntryById(SnapshotObjectId id) : id_(id) { } - int operator()(HeapEntry* const* entry) { - if ((*entry)->id() == id_) return 0; - return (*entry)->id() < id_ ? -1 : 1; - } - private: - SnapshotObjectId id_; -}; - - HeapEntry* HeapSnapshot::GetEntryById(SnapshotObjectId id) { List<HeapEntry*>* entries_by_id = GetSortedEntriesList(); + // Perform a binary search by id. - int index = SortedListBSearch(*entries_by_id, FindEntryById(id)); - if (index == -1) - return NULL; - return entries_by_id->at(index); + int low = 0; + int high = entries_by_id->length() - 1; + while (low <= high) { + int mid = + (static_cast<unsigned int>(low) + static_cast<unsigned int>(high)) >> 1; + SnapshotObjectId mid_id = entries_by_id->at(mid)->id(); + if (mid_id > id) + high = mid - 1; + else if (mid_id < id) + low = mid + 1; + else + return entries_by_id->at(mid); + } + return NULL; } @@ -1286,11 +1279,11 @@ static int SortByIds(const T* entry1_ptr, List<HeapEntry*>* HeapSnapshot::GetSortedEntriesList() { - if (sorted_entries_.is_empty()) { - sorted_entries_.AddAll(entries_); - sorted_entries_.Sort(SortByIds); + if (!entries_sorted_) { + entries_.Sort(SortByIds); + entries_sorted_ = true; } - return &sorted_entries_; + return &entries_; } @@ -1311,166 +1304,96 @@ const SnapshotObjectId HeapObjectsMap::kFirstAvailableObjectId = VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; HeapObjectsMap::HeapObjectsMap() - : next_id_(kFirstAvailableObjectId), - entries_map_(AddressesMatch) { - // This dummy element solves a problem with entries_map_. - // When we do lookup in HashMap we see no difference between two cases: - // it has an entry with NULL as the value or it has created - // a new entry on the fly with NULL as the default value. - // With such dummy element we have a guaranty that all entries_map_ entries - // will have the value field grater than 0. - // This fact is using in MoveObject method. - entries_.Add(EntryInfo(0, NULL, 0)); + : initial_fill_mode_(true), + next_id_(kFirstAvailableObjectId), + entries_map_(AddressesMatch), + entries_(new List<EntryInfo>()) { } + + +HeapObjectsMap::~HeapObjectsMap() { + delete entries_; } void HeapObjectsMap::SnapshotGenerationFinished() { + initial_fill_mode_ = false; RemoveDeadEntries(); } +SnapshotObjectId HeapObjectsMap::FindObject(Address addr) { + if (!initial_fill_mode_) { + SnapshotObjectId existing = FindEntry(addr); + if (existing != 0) return existing; + } + SnapshotObjectId id = next_id_; + next_id_ += kObjectIdStep; + AddEntry(addr, id); + return id; +} + + void HeapObjectsMap::MoveObject(Address from, Address to) { - ASSERT(to != NULL); - ASSERT(from != NULL); if (from == to) return; - void* from_value = entries_map_.Remove(from, AddressHash(from)); - if (from_value == NULL) return; - int from_entry_info_index = - static_cast<int>(reinterpret_cast<intptr_t>(from_value)); - entries_.at(from_entry_info_index).addr = to; - HashMap::Entry* to_entry = entries_map_.Lookup(to, AddressHash(to), true); - if (to_entry->value != NULL) { - int to_entry_info_index = - static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); - // Without this operation we will have two EntryInfo's with the same - // value in addr field. It is bad because later at RemoveDeadEntries - // one of this entry will be removed with the corresponding entries_map_ - // entry. - entries_.at(to_entry_info_index).addr = NULL; + HashMap::Entry* entry = entries_map_.Lookup(from, AddressHash(from), false); + if (entry != NULL) { + void* value = entry->value; + entries_map_.Remove(from, AddressHash(from)); + if (to != NULL) { + entry = entries_map_.Lookup(to, AddressHash(to), true); + // We can have an entry at the new location, it is OK, as GC can overwrite + // dead objects with alive objects being moved. + entry->value = value; + } } - to_entry->value = reinterpret_cast<void*>(from_entry_info_index); } -SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { - HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), false); - if (entry == NULL) return 0; - int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); - EntryInfo& entry_info = entries_.at(entry_index); - ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); - return entry_info.id; +void HeapObjectsMap::AddEntry(Address addr, SnapshotObjectId id) { + HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true); + ASSERT(entry->value == NULL); + entry->value = reinterpret_cast<void*>(entries_->length()); + entries_->Add(EntryInfo(id)); } -SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, - unsigned int size) { - ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); - HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true); - if (entry->value != NULL) { +SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { + HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), false); + if (entry != NULL) { int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); - EntryInfo& entry_info = entries_.at(entry_index); + EntryInfo& entry_info = entries_->at(entry_index); entry_info.accessed = true; - entry_info.size = size; return entry_info.id; + } else { + return 0; } - entry->value = reinterpret_cast<void*>(entries_.length()); - SnapshotObjectId id = next_id_; - next_id_ += kObjectIdStep; - entries_.Add(EntryInfo(id, addr, size)); - ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); - return id; -} - - -void HeapObjectsMap::StopHeapObjectsTracking() { - time_intervals_.Clear(); -} - -void HeapObjectsMap::UpdateHeapObjectsMap() { - HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, - "HeapSnapshotsCollection::UpdateHeapObjectsMap"); - HeapIterator iterator; - for (HeapObject* obj = iterator.next(); - obj != NULL; - obj = iterator.next()) { - FindOrAddEntry(obj->address(), obj->Size()); - } - RemoveDeadEntries(); -} - - -void HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { - UpdateHeapObjectsMap(); - time_intervals_.Add(TimeInterval(next_id_)); - int prefered_chunk_size = stream->GetChunkSize(); - List<v8::HeapStatsUpdate> stats_buffer; - ASSERT(!entries_.is_empty()); - EntryInfo* entry_info = &entries_.first(); - EntryInfo* end_entry_info = &entries_.last() + 1; - for (int time_interval_index = 0; - time_interval_index < time_intervals_.length(); - ++time_interval_index) { - TimeInterval& time_interval = time_intervals_[time_interval_index]; - SnapshotObjectId time_interval_id = time_interval.id; - uint32_t entries_size = 0; - EntryInfo* start_entry_info = entry_info; - while (entry_info < end_entry_info && entry_info->id < time_interval_id) { - entries_size += entry_info->size; - ++entry_info; - } - uint32_t entries_count = - static_cast<uint32_t>(entry_info - start_entry_info); - if (time_interval.count != entries_count || - time_interval.size != entries_size) { - stats_buffer.Add(v8::HeapStatsUpdate( - time_interval_index, - time_interval.count = entries_count, - time_interval.size = entries_size)); - if (stats_buffer.length() >= prefered_chunk_size) { - OutputStream::WriteResult result = stream->WriteHeapStatsChunk( - &stats_buffer.first(), stats_buffer.length()); - if (result == OutputStream::kAbort) return; - stats_buffer.Clear(); - } - } - } - ASSERT(entry_info == end_entry_info); - if (!stats_buffer.is_empty()) { - OutputStream::WriteResult result = stream->WriteHeapStatsChunk( - &stats_buffer.first(), stats_buffer.length()); - if (result == OutputStream::kAbort) return; - } - stream->EndOfStream(); } void HeapObjectsMap::RemoveDeadEntries() { - ASSERT(entries_.length() > 0 && - entries_.at(0).id == 0 && - entries_.at(0).addr == NULL); - int first_free_entry = 1; - for (int i = 1; i < entries_.length(); ++i) { - EntryInfo& entry_info = entries_.at(i); + List<EntryInfo>* new_entries = new List<EntryInfo>(); + List<void*> dead_entries; + for (HashMap::Entry* entry = entries_map_.Start(); + entry != NULL; + entry = entries_map_.Next(entry)) { + int entry_index = + static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); + EntryInfo& entry_info = entries_->at(entry_index); if (entry_info.accessed) { - if (first_free_entry != i) { - entries_.at(first_free_entry) = entry_info; - } - entries_.at(first_free_entry).accessed = false; - HashMap::Entry* entry = entries_map_.Lookup( - entry_info.addr, AddressHash(entry_info.addr), false); - ASSERT(entry); - entry->value = reinterpret_cast<void*>(first_free_entry); - ++first_free_entry; + entry->value = reinterpret_cast<void*>(new_entries->length()); + new_entries->Add(EntryInfo(entry_info.id, false)); } else { - if (entry_info.addr) { - entries_map_.Remove(entry_info.addr, AddressHash(entry_info.addr)); - } + dead_entries.Add(entry->key); } } - entries_.Rewind(first_free_entry); - ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == - entries_map_.occupancy()); + for (int i = 0; i < dead_entries.length(); ++i) { + void* raw_entry = dead_entries[i]; + entries_map_.Remove( + raw_entry, AddressHash(reinterpret_cast<Address>(raw_entry))); + } + delete entries_; + entries_ = new_entries; } @@ -1557,7 +1480,7 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById( for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { - if (ids_.FindEntry(obj->address()) == id) { + if (ids_.FindObject(obj->address()) == id) { ASSERT(object == NULL); object = obj; // Can't break -- kFilterUnreachable requires full heap traversal. @@ -1585,39 +1508,20 @@ HeapEntriesMap::~HeapEntriesMap() { } -void HeapEntriesMap::AllocateHeapEntryForMapEntry(HashMap::Entry* map_entry) { - EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(map_entry->value); +void HeapEntriesMap::AllocateEntries() { + for (HashMap::Entry* p = entries_.Start(); + p != NULL; + p = entries_.Next(p)) { + EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value); entry_info->entry = entry_info->allocator->AllocateEntry( - map_entry->key, + p->key, entry_info->children_count, entry_info->retainers_count); ASSERT(entry_info->entry != NULL); ASSERT(entry_info->entry != kHeapEntryPlaceholder); entry_info->children_count = 0; entry_info->retainers_count = 0; -} - - -void HeapEntriesMap::AllocateEntries(HeapThing root_object) { - HashMap::Entry* root_entry = - entries_.Lookup(root_object, Hash(root_object), false); - ASSERT(root_entry != NULL); - // Make sure root entry is allocated first. - AllocateHeapEntryForMapEntry(root_entry); - void* root_entry_value = root_entry->value; - // Remove the root object from map while iterating through other entries. - entries_.Remove(root_object, Hash(root_object)); - root_entry = NULL; - - for (HashMap::Entry* p = entries_.Start(); - p != NULL; - p = entries_.Next(p)) { - AllocateHeapEntryForMapEntry(p); } - - // Insert root entry back. - root_entry = entries_.Lookup(root_object, Hash(root_object), true); - root_entry->value = root_entry_value; } @@ -1858,13 +1762,10 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, const char* name, int children_count, int retainers_count) { - int object_size = object->Size(); - SnapshotObjectId object_id = - collection_->GetObjectId(object->address(), object_size); return snapshot_->AddEntry(type, name, - object_id, - object_size, + collection_->GetObjectId(object->address()), + object->Size(), children_count, retainers_count); } @@ -1978,285 +1879,173 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) { bool extract_indexed_refs = true; if (obj->IsJSGlobalProxy()) { - ExtractJSGlobalProxyReferences(JSGlobalProxy::cast(obj)); + // We need to reference JS global objects from snapshot's root. + // We use JSGlobalProxy because this is what embedder (e.g. browser) + // uses for the global object. + JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); + SetRootShortcutReference(proxy->map()->prototype()); } else if (obj->IsJSObject()) { - ExtractJSObjectReferences(entry, JSObject::cast(obj)); - } else if (obj->IsString()) { - ExtractStringReferences(entry, String::cast(obj)); - extract_indexed_refs = false; - } else if (obj->IsContext()) { - ExtractContextReferences(entry, Context::cast(obj)); - } else if (obj->IsMap()) { - ExtractMapReferences(entry, Map::cast(obj)); - } else if (obj->IsSharedFunctionInfo()) { - ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); - } else if (obj->IsScript()) { - ExtractScriptReferences(entry, Script::cast(obj)); - } else if (obj->IsCodeCache()) { - ExtractCodeCacheReferences(entry, CodeCache::cast(obj)); - } else if (obj->IsCode()) { - ExtractCodeReferences(entry, Code::cast(obj)); - } else if (obj->IsJSGlobalPropertyCell()) { - ExtractJSGlobalPropertyCellReferences( - entry, JSGlobalPropertyCell::cast(obj)); - extract_indexed_refs = false; - } - if (extract_indexed_refs) { - SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); - IndexedReferencesExtractor refs_extractor(this, obj, entry); - obj->Iterate(&refs_extractor); - } -} - - -void V8HeapExplorer::ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy) { - // We need to reference JS global objects from snapshot's root. - // We use JSGlobalProxy because this is what embedder (e.g. browser) - // uses for the global object. - Object* object = proxy->map()->prototype(); - bool is_debug_object = false; -#ifdef ENABLE_DEBUGGER_SUPPORT - is_debug_object = object->IsGlobalObject() && - Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object)); -#endif - if (!is_debug_object) { - SetUserGlobalReference(object); - } -} - - -void V8HeapExplorer::ExtractJSObjectReferences( - HeapEntry* entry, JSObject* js_obj) { - HeapObject* obj = js_obj; - ExtractClosureReferences(js_obj, entry); - ExtractPropertyReferences(js_obj, entry); - ExtractElementReferences(js_obj, entry); - ExtractInternalReferences(js_obj, entry); - SetPropertyReference( - obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); - if (obj->IsJSFunction()) { - JSFunction* js_fun = JSFunction::cast(js_obj); - Object* proto_or_map = js_fun->prototype_or_initial_map(); - if (!proto_or_map->IsTheHole()) { - if (!proto_or_map->IsMap()) { - SetPropertyReference( - obj, entry, - heap_->prototype_symbol(), proto_or_map, - NULL, - JSFunction::kPrototypeOrInitialMapOffset); - } else { - SetPropertyReference( - obj, entry, - heap_->prototype_symbol(), js_fun->prototype()); + JSObject* js_obj = JSObject::cast(obj); + ExtractClosureReferences(js_obj, entry); + ExtractPropertyReferences(js_obj, entry); + ExtractElementReferences(js_obj, entry); + ExtractInternalReferences(js_obj, entry); + SetPropertyReference( + obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); + if (obj->IsJSFunction()) { + JSFunction* js_fun = JSFunction::cast(js_obj); + Object* proto_or_map = js_fun->prototype_or_initial_map(); + if (!proto_or_map->IsTheHole()) { + if (!proto_or_map->IsMap()) { + SetPropertyReference( + obj, entry, + heap_->prototype_symbol(), proto_or_map, + NULL, + JSFunction::kPrototypeOrInitialMapOffset); + } else { + SetPropertyReference( + obj, entry, + heap_->prototype_symbol(), js_fun->prototype()); + } } + SharedFunctionInfo* shared_info = js_fun->shared(); + // JSFunction has either bindings or literals and never both. + bool bound = shared_info->bound(); + TagObject(js_fun->literals_or_bindings(), + bound ? "(function bindings)" : "(function literals)"); + SetInternalReference(js_fun, entry, + bound ? "bindings" : "literals", + js_fun->literals_or_bindings(), + JSFunction::kLiteralsOffset); + SetInternalReference(js_fun, entry, + "shared", shared_info, + JSFunction::kSharedFunctionInfoOffset); + TagObject(js_fun->unchecked_context(), "(context)"); + SetInternalReference(js_fun, entry, + "context", js_fun->unchecked_context(), + JSFunction::kContextOffset); + for (int i = JSFunction::kNonWeakFieldsEndOffset; + i < JSFunction::kSize; + i += kPointerSize) { + SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); + } + } + TagObject(js_obj->properties(), "(object properties)"); + SetInternalReference(obj, entry, + "properties", js_obj->properties(), + JSObject::kPropertiesOffset); + TagObject(js_obj->elements(), "(object elements)"); + SetInternalReference(obj, entry, + "elements", js_obj->elements(), + JSObject::kElementsOffset); + } else if (obj->IsString()) { + if (obj->IsConsString()) { + ConsString* cs = ConsString::cast(obj); + SetInternalReference(obj, entry, 1, cs->first()); + SetInternalReference(obj, entry, 2, cs->second()); } - SharedFunctionInfo* shared_info = js_fun->shared(); - // JSFunction has either bindings or literals and never both. - bool bound = shared_info->bound(); - TagObject(js_fun->literals_or_bindings(), - bound ? "(function bindings)" : "(function literals)"); - SetInternalReference(js_fun, entry, - bound ? "bindings" : "literals", - js_fun->literals_or_bindings(), - JSFunction::kLiteralsOffset); - TagObject(shared_info, "(shared function info)"); - SetInternalReference(js_fun, entry, - "shared", shared_info, - JSFunction::kSharedFunctionInfoOffset); - TagObject(js_fun->unchecked_context(), "(context)"); - SetInternalReference(js_fun, entry, - "context", js_fun->unchecked_context(), - JSFunction::kContextOffset); - for (int i = JSFunction::kNonWeakFieldsEndOffset; - i < JSFunction::kSize; - i += kPointerSize) { - SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); + if (obj->IsSlicedString()) { + SlicedString* ss = SlicedString::cast(obj); + SetInternalReference(obj, entry, "parent", ss->parent()); } - } else if (obj->IsGlobalObject()) { - GlobalObject* global_obj = GlobalObject::cast(obj); - SetInternalReference(global_obj, entry, - "builtins", global_obj->builtins(), - GlobalObject::kBuiltinsOffset); - SetInternalReference(global_obj, entry, - "global_context", global_obj->global_context(), - GlobalObject::kGlobalContextOffset); - SetInternalReference(global_obj, entry, - "global_receiver", global_obj->global_receiver(), - GlobalObject::kGlobalReceiverOffset); - } - TagObject(js_obj->properties(), "(object properties)"); - SetInternalReference(obj, entry, - "properties", js_obj->properties(), - JSObject::kPropertiesOffset); - TagObject(js_obj->elements(), "(object elements)"); - SetInternalReference(obj, entry, - "elements", js_obj->elements(), - JSObject::kElementsOffset); -} - - -void V8HeapExplorer::ExtractStringReferences(HeapEntry* entry, String* string) { - if (string->IsConsString()) { - ConsString* cs = ConsString::cast(string); - SetInternalReference(cs, entry, "first", cs->first()); - SetInternalReference(cs, entry, "second", cs->second()); - } else if (string->IsSlicedString()) { - SlicedString* ss = SlicedString::cast(string); - SetInternalReference(ss, entry, "parent", ss->parent()); - } -} - - -void V8HeapExplorer::ExtractContextReferences( - HeapEntry* entry, Context* context) { -#define EXTRACT_CONTEXT_FIELD(index, type, name) \ - SetInternalReference(context, entry, #name, context->get(Context::index), \ - FixedArray::OffsetOfElementAt(Context::index)); - EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); - EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); - EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); - EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global); - if (context->IsGlobalContext()) { + extract_indexed_refs = false; + } else if (obj->IsGlobalContext()) { + Context* context = Context::cast(obj); TagObject(context->jsfunction_result_caches(), "(context func. result caches)"); TagObject(context->normalized_map_cache(), "(context norm. map cache)"); TagObject(context->runtime_context(), "(runtime context)"); TagObject(context->data(), "(context data)"); - GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); -#undef EXTRACT_CONTEXT_FIELD for (int i = Context::FIRST_WEAK_SLOT; i < Context::GLOBAL_CONTEXT_SLOTS; ++i) { - SetWeakReference(context, entry, i, context->get(i), - FixedArray::OffsetOfElementAt(i)); + SetWeakReference(obj, entry, + i, context->get(i), + FixedArray::OffsetOfElementAt(i)); + } + } else if (obj->IsMap()) { + Map* map = Map::cast(obj); + SetInternalReference(obj, entry, + "prototype", map->prototype(), Map::kPrototypeOffset); + SetInternalReference(obj, entry, + "constructor", map->constructor(), + Map::kConstructorOffset); + if (!map->instance_descriptors()->IsEmpty()) { + TagObject(map->instance_descriptors(), "(map descriptors)"); + SetInternalReference(obj, entry, + "descriptors", map->instance_descriptors(), + Map::kInstanceDescriptorsOrBitField3Offset); + } + if (map->prototype_transitions() != heap_->empty_fixed_array()) { + TagObject(map->prototype_transitions(), "(prototype transitions)"); + SetInternalReference(obj, + entry, + "prototype_transitions", + map->prototype_transitions(), + Map::kPrototypeTransitionsOffset); } + SetInternalReference(obj, entry, + "code_cache", map->code_cache(), + Map::kCodeCacheOffset); + } else if (obj->IsSharedFunctionInfo()) { + SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); + SetInternalReference(obj, entry, + "name", shared->name(), + SharedFunctionInfo::kNameOffset); + SetInternalReference(obj, entry, + "code", shared->unchecked_code(), + SharedFunctionInfo::kCodeOffset); + TagObject(shared->scope_info(), "(function scope info)"); + SetInternalReference(obj, entry, + "scope_info", shared->scope_info(), + SharedFunctionInfo::kScopeInfoOffset); + SetInternalReference(obj, entry, + "instance_class_name", shared->instance_class_name(), + SharedFunctionInfo::kInstanceClassNameOffset); + SetInternalReference(obj, entry, + "script", shared->script(), + SharedFunctionInfo::kScriptOffset); + SetWeakReference(obj, entry, + 1, shared->initial_map(), + SharedFunctionInfo::kInitialMapOffset); + } else if (obj->IsScript()) { + Script* script = Script::cast(obj); + SetInternalReference(obj, entry, + "source", script->source(), + Script::kSourceOffset); + SetInternalReference(obj, entry, + "name", script->name(), + Script::kNameOffset); + SetInternalReference(obj, entry, + "data", script->data(), + Script::kDataOffset); + SetInternalReference(obj, entry, + "context_data", script->context_data(), + Script::kContextOffset); + TagObject(script->line_ends(), "(script line ends)"); + SetInternalReference(obj, entry, + "line_ends", script->line_ends(), + Script::kLineEndsOffset); + } else if (obj->IsCodeCache()) { + CodeCache* code_cache = CodeCache::cast(obj); + TagObject(code_cache->default_cache(), "(default code cache)"); + SetInternalReference(obj, entry, + "default_cache", code_cache->default_cache(), + CodeCache::kDefaultCacheOffset); + TagObject(code_cache->normal_type_cache(), "(code type cache)"); + SetInternalReference(obj, entry, + "type_cache", code_cache->normal_type_cache(), + CodeCache::kNormalTypeCacheOffset); + } else if (obj->IsCode()) { + Code* code = Code::cast(obj); + TagObject(code->unchecked_relocation_info(), "(code relocation info)"); + TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); + } + if (extract_indexed_refs) { + SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); + IndexedReferencesExtractor refs_extractor(this, obj, entry); + obj->Iterate(&refs_extractor); } -} - - -void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { - SetInternalReference(map, entry, - "prototype", map->prototype(), Map::kPrototypeOffset); - SetInternalReference(map, entry, - "constructor", map->constructor(), - Map::kConstructorOffset); - if (!map->instance_descriptors()->IsEmpty()) { - TagObject(map->instance_descriptors(), "(map descriptors)"); - SetInternalReference(map, entry, - "descriptors", map->instance_descriptors(), - Map::kInstanceDescriptorsOrBitField3Offset); - } - TagObject(map->prototype_transitions(), "(prototype transitions)"); - SetInternalReference(map, entry, - "prototype_transitions", map->prototype_transitions(), - Map::kPrototypeTransitionsOffset); - SetInternalReference(map, entry, - "code_cache", map->code_cache(), - Map::kCodeCacheOffset); -} - - -void V8HeapExplorer::ExtractSharedFunctionInfoReferences( - HeapEntry* entry, SharedFunctionInfo* shared) { - HeapObject* obj = shared; - SetInternalReference(obj, entry, - "name", shared->name(), - SharedFunctionInfo::kNameOffset); - TagObject(shared->code(), "(code)"); - SetInternalReference(obj, entry, - "code", shared->code(), - SharedFunctionInfo::kCodeOffset); - TagObject(shared->scope_info(), "(function scope info)"); - SetInternalReference(obj, entry, - "scope_info", shared->scope_info(), - SharedFunctionInfo::kScopeInfoOffset); - SetInternalReference(obj, entry, - "instance_class_name", shared->instance_class_name(), - SharedFunctionInfo::kInstanceClassNameOffset); - SetInternalReference(obj, entry, - "script", shared->script(), - SharedFunctionInfo::kScriptOffset); - TagObject(shared->construct_stub(), "(code)"); - SetInternalReference(obj, entry, - "construct_stub", shared->construct_stub(), - SharedFunctionInfo::kConstructStubOffset); - SetInternalReference(obj, entry, - "function_data", shared->function_data(), - SharedFunctionInfo::kFunctionDataOffset); - SetInternalReference(obj, entry, - "debug_info", shared->debug_info(), - SharedFunctionInfo::kDebugInfoOffset); - SetInternalReference(obj, entry, - "inferred_name", shared->inferred_name(), - SharedFunctionInfo::kInferredNameOffset); - SetInternalReference(obj, entry, - "this_property_assignments", - shared->this_property_assignments(), - SharedFunctionInfo::kThisPropertyAssignmentsOffset); - SetWeakReference(obj, entry, - 1, shared->initial_map(), - SharedFunctionInfo::kInitialMapOffset); -} - - -void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry, Script* script) { - HeapObject* obj = script; - SetInternalReference(obj, entry, - "source", script->source(), - Script::kSourceOffset); - SetInternalReference(obj, entry, - "name", script->name(), - Script::kNameOffset); - SetInternalReference(obj, entry, - "data", script->data(), - Script::kDataOffset); - SetInternalReference(obj, entry, - "context_data", script->context_data(), - Script::kContextOffset); - TagObject(script->line_ends(), "(script line ends)"); - SetInternalReference(obj, entry, - "line_ends", script->line_ends(), - Script::kLineEndsOffset); -} - - -void V8HeapExplorer::ExtractCodeCacheReferences( - HeapEntry* entry, CodeCache* code_cache) { - TagObject(code_cache->default_cache(), "(default code cache)"); - SetInternalReference(code_cache, entry, - "default_cache", code_cache->default_cache(), - CodeCache::kDefaultCacheOffset); - TagObject(code_cache->normal_type_cache(), "(code type cache)"); - SetInternalReference(code_cache, entry, - "type_cache", code_cache->normal_type_cache(), - CodeCache::kNormalTypeCacheOffset); -} - - -void V8HeapExplorer::ExtractCodeReferences(HeapEntry* entry, Code* code) { - TagObject(code->relocation_info(), "(code relocation info)"); - SetInternalReference(code, entry, - "relocation_info", code->relocation_info(), - Code::kRelocationInfoOffset); - SetInternalReference(code, entry, - "handler_table", code->handler_table(), - Code::kHandlerTableOffset); - TagObject(code->deoptimization_data(), "(code deopt data)"); - SetInternalReference(code, entry, - "deoptimization_data", code->deoptimization_data(), - Code::kDeoptimizationDataOffset); - SetInternalReference(code, entry, - "type_feedback_info", code->type_feedback_info(), - Code::kTypeFeedbackInfoOffset); - SetInternalReference(code, entry, - "gc_metadata", code->gc_metadata(), - Code::kGCMetadataOffset); -} - - -void V8HeapExplorer::ExtractJSGlobalPropertyCellReferences( - HeapEntry* entry, JSGlobalPropertyCell* cell) { - SetInternalReference(cell, entry, "value", cell->value()); } @@ -2265,6 +2054,9 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, if (!js_obj->IsJSFunction()) return; JSFunction* func = JSFunction::cast(js_obj); + Context* context = func->context(); + ScopeInfo* scope_info = context->closure()->shared()->scope_info(); + if (func->shared()->bound()) { FixedArray* bindings = func->function_bindings(); SetNativeBindReference(js_obj, entry, "bound_this", @@ -2280,8 +2072,6 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, bindings->get(i)); } } else { - Context* context = func->context()->declaration_context(); - ScopeInfo* scope_info = context->closure()->shared()->scope_info(); // Add context allocated locals. int context_locals = scope_info->ContextLocalCount(); for (int i = 0; i < context_locals; ++i) { @@ -2293,11 +2083,12 @@ void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, // Add function variable. if (scope_info->HasFunctionName()) { String* name = scope_info->FunctionName(); + int idx = Context::MIN_CONTEXT_SLOTS + context_locals; +#ifdef DEBUG VariableMode mode; - int idx = scope_info->FunctionContextSlotIndex(name, &mode); - if (idx >= 0) { - SetClosureReference(js_obj, entry, name, context->get(idx)); - } + ASSERT(idx == scope_info->FunctionContextSlotIndex(name, &mode)); +#endif + SetClosureReference(js_obj, entry, name, context->get(idx)); } } } @@ -2361,15 +2152,15 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, Object* k = dictionary->KeyAt(i); if (dictionary->IsKey(k)) { Object* target = dictionary->ValueAt(i); + SetPropertyReference( + js_obj, entry, String::cast(k), target); // We assume that global objects can only have slow properties. - Object* value = target->IsJSGlobalPropertyCell() - ? JSGlobalPropertyCell::cast(target)->value() - : target; - if (String::cast(k)->length() > 0) { - SetPropertyReference(js_obj, entry, String::cast(k), value); - } else { - TagObject(value, "(hidden properties)"); - SetInternalReference(js_obj, entry, "hidden_properties", value); + if (target->IsJSGlobalPropertyCell()) { + SetPropertyShortcutReference(js_obj, + entry, + String::cast(k), + JSGlobalPropertyCell::cast( + target)->value()); } } } @@ -2568,23 +2359,6 @@ void V8HeapExplorer::SetObjectName(HeapObject* object) { } -bool V8HeapExplorer::IsEssentialObject(Object* object) { - // We have to use raw_unchecked_* versions because checked versions - // would fail during iteration over object properties. - return object->IsHeapObject() - && !object->IsOddball() - && object != heap_->raw_unchecked_empty_byte_array() - && object != heap_->raw_unchecked_empty_fixed_array() - && object != heap_->raw_unchecked_empty_descriptor_array() - && object != heap_->raw_unchecked_fixed_array_map() - && object != heap_->raw_unchecked_global_property_cell_map() - && object != heap_->raw_unchecked_shared_function_info_map() - && object != heap_->raw_unchecked_free_space_map() - && object != heap_->raw_unchecked_one_pointer_filler_map() - && object != heap_->raw_unchecked_two_pointer_filler_map(); -} - - void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj, HeapEntry* parent_entry, String* reference_name, @@ -2639,14 +2413,15 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, Object* child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); - if (child_entry == NULL) return; - if (IsEssentialObject(child_obj)) { + if (child_entry != NULL) { filler_->SetNamedReference(HeapGraphEdge::kInternal, - parent_obj, parent_entry, + parent_obj, + parent_entry, reference_name, - child_obj, child_entry); + child_obj, + child_entry); + IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); } - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); } @@ -2656,14 +2431,15 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, Object* child_obj, int field_offset) { HeapEntry* child_entry = GetEntry(child_obj); - if (child_entry == NULL) return; - if (IsEssentialObject(child_obj)) { + if (child_entry != NULL) { filler_->SetNamedReference(HeapGraphEdge::kInternal, - parent_obj, parent_entry, + parent_obj, + parent_entry, collection_->names()->GetName(index), - child_obj, child_entry); + child_obj, + child_entry); + IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); } - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); } @@ -2672,7 +2448,7 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, int index, Object* child_obj) { HeapEntry* child_entry = GetEntry(child_obj); - if (child_entry != NULL && IsEssentialObject(child_obj)) { + if (child_entry != NULL) { filler_->SetIndexedReference(HeapGraphEdge::kHidden, parent_obj, parent_entry, @@ -2753,7 +2529,7 @@ void V8HeapExplorer::SetRootGcRootsReference() { } -void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) { +void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) { HeapEntry* child_entry = GetEntry(child_obj); ASSERT(child_entry != NULL); filler_->SetNamedAutoIndexReference( @@ -2775,44 +2551,20 @@ void V8HeapExplorer::SetGcSubrootReference( VisitorSynchronization::SyncTag tag, bool is_weak, Object* child_obj) { HeapEntry* child_entry = GetEntry(child_obj); if (child_entry != NULL) { - const char* name = GetStrongGcSubrootName(child_obj); - if (name != NULL) { - filler_->SetNamedReference( - HeapGraphEdge::kInternal, - GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), - name, - child_obj, child_entry); - } else { - filler_->SetIndexedAutoIndexReference( - is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement, - GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), - child_obj, child_entry); - } - } -} - - -const char* V8HeapExplorer::GetStrongGcSubrootName(Object* object) { - if (strong_gc_subroot_names_.is_empty()) { -#define NAME_ENTRY(name) strong_gc_subroot_names_.SetTag(heap_->name(), #name); -#define ROOT_NAME(type, name, camel_name) NAME_ENTRY(name) - STRONG_ROOT_LIST(ROOT_NAME) -#undef ROOT_NAME -#define STRUCT_MAP_NAME(NAME, Name, name) NAME_ENTRY(name##_map) - STRUCT_LIST(STRUCT_MAP_NAME) -#undef STRUCT_MAP_NAME -#define SYMBOL_NAME(name, str) NAME_ENTRY(name) - SYMBOL_LIST(SYMBOL_NAME) -#undef SYMBOL_NAME -#undef NAME_ENTRY - CHECK(!strong_gc_subroot_names_.is_empty()); + filler_->SetIndexedAutoIndexReference( + is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement, + GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag), + child_obj, child_entry); } - return strong_gc_subroot_names_.GetTag(object); } void V8HeapExplorer::TagObject(Object* obj, const char* tag) { - if (IsEssentialObject(obj)) { + if (obj->IsHeapObject() && + !obj->IsOddball() && + obj != heap_->raw_unchecked_empty_byte_array() && + obj != heap_->raw_unchecked_empty_fixed_array() && + obj != heap_->raw_unchecked_empty_descriptor_array()) { objects_tags_.SetTag(obj, tag); } } @@ -2859,7 +2611,7 @@ void V8HeapExplorer::TagGlobalObjects() { Handle<JSGlobalObject> global_obj = enumerator.at(i); Object* obj_document; if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) && - obj_document->IsJSObject()) { + obj_document->IsJSObject()) { JSObject* document = JSObject::cast(obj_document); Object* obj_url; if (document->GetProperty(*url_string)->ToObject(&obj_url) && @@ -3348,13 +3100,11 @@ bool HeapSnapshotGenerator::GenerateSnapshot() { entries_.total_retainers_count()); // Allocate heap objects to entries hash map. - entries_.AllocateEntries(V8HeapExplorer::kInternalRootObject); + entries_.AllocateEntries(); // Pass 2. Fill references. if (!FillReferences()) return false; - snapshot_->RememberLastJSObjectId(); - if (!SetEntriesDominators()) return false; if (!CalculateRetainedSizes()) return false; @@ -3413,61 +3163,19 @@ bool HeapSnapshotGenerator::FillReferences() { } -bool HeapSnapshotGenerator::IsUserGlobalReference(const HeapGraphEdge& edge) { - ASSERT(edge.from() == snapshot_->root()); - return edge.type() == HeapGraphEdge::kShortcut; -} - - -void HeapSnapshotGenerator::MarkUserReachableObjects() { - List<HeapEntry*> worklist; - - Vector<HeapGraphEdge> children = snapshot_->root()->children(); - for (int i = 0; i < children.length(); ++i) { - if (IsUserGlobalReference(children[i])) { - worklist.Add(children[i].to()); - } - } - - while (!worklist.is_empty()) { - HeapEntry* entry = worklist.RemoveLast(); - if (entry->user_reachable()) continue; - entry->set_user_reachable(); - Vector<HeapGraphEdge> children = entry->children(); - for (int i = 0; i < children.length(); ++i) { - HeapEntry* child = children[i].to(); - if (!child->user_reachable()) { - worklist.Add(child); - } - } - } -} - - -static bool IsRetainingEdge(HeapGraphEdge* edge) { - if (edge->type() == HeapGraphEdge::kShortcut) return false; - // The edge is not retaining if it goes from system domain - // (i.e. an object not reachable from window) to the user domain - // (i.e. a reachable object). - return edge->from()->user_reachable() - || !edge->to()->user_reachable(); -} - - -void HeapSnapshotGenerator::FillPostorderIndexes( +void HeapSnapshotGenerator::FillReversePostorderIndexes( Vector<HeapEntry*>* entries) { snapshot_->ClearPaint(); int current_entry = 0; List<HeapEntry*> nodes_to_visit; - HeapEntry* root = snapshot_->root(); - nodes_to_visit.Add(root); + nodes_to_visit.Add(snapshot_->root()); snapshot_->root()->paint(); while (!nodes_to_visit.is_empty()) { HeapEntry* entry = nodes_to_visit.last(); Vector<HeapGraphEdge> children = entry->children(); bool has_new_edges = false; for (int i = 0; i < children.length(); ++i) { - if (entry != root && !IsRetainingEdge(&children[i])) continue; + if (children[i].type() == HeapGraphEdge::kShortcut) continue; HeapEntry* child = children[i].to(); if (!child->painted()) { nodes_to_visit.Add(child); @@ -3502,7 +3210,6 @@ bool HeapSnapshotGenerator::BuildDominatorTree( const Vector<HeapEntry*>& entries, Vector<int>* dominators) { if (entries.length() == 0) return true; - HeapEntry* root = snapshot_->root(); const int entries_length = entries.length(), root_index = entries_length - 1; static const int kNoDominator = -1; for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; @@ -3531,8 +3238,8 @@ bool HeapSnapshotGenerator::BuildDominatorTree( int new_idom_index = kNoDominator; Vector<HeapGraphEdge*> rets = entries[i]->retainers(); for (int j = 0; j < rets.length(); ++j) { - if (rets[j]->from() != root && !IsRetainingEdge(rets[j])) continue; - int ret_index = rets[j]->from()->ordered_index(); + if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; + int ret_index = rets[j]->From()->ordered_index(); if (dominators->at(ret_index) != kNoDominator) { new_idom_index = new_idom_index == kNoDominator ? ret_index @@ -3558,10 +3265,9 @@ bool HeapSnapshotGenerator::BuildDominatorTree( bool HeapSnapshotGenerator::SetEntriesDominators() { - MarkUserReachableObjects(); - // This array is used for maintaining postorder of nodes. + // This array is used for maintaining reverse postorder of nodes. ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); - FillPostorderIndexes(&ordered_entries); + FillReversePostorderIndexes(&ordered_entries); ScopedVector<int> dominators(ordered_entries.length()); if (!BuildDominatorTree(ordered_entries, &dominators)) return false; for (int i = 0; i < ordered_entries.length(); ++i) { @@ -3639,7 +3345,9 @@ class OutputStreamWriter { MaybeWriteChunk(); } } + void AddNumber(int n) { AddNumberImpl<int>(n, "%d"); } void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } + void AddNumber(uint64_t n) { AddNumberImpl<uint64_t>(n, "%llu"); } void Finalize() { if (aborted_) return; ASSERT(chunk_pos_ < chunk_size_); @@ -3703,6 +3411,7 @@ void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { } // Since nodes graph is cyclic, we need the first pass to enumerate // them. Strings can be serialized in one pass. + EnumerateNodes(); SerializeImpl(); delete writer_; @@ -3736,37 +3445,14 @@ HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() { } -void HeapSnapshotJSONSerializer::CalculateNodeIndexes( - const List<HeapEntry*>& nodes) { - // type,name,id,self_size,retained_size,dominator,children_index. - const int node_fields_count = 7; - // Root must be the first. - ASSERT(nodes.first() == snapshot_->root()); - // Rewrite node indexes, so they refer to actual array positions. Do this - // only once. - if (nodes[0]->entry_index() == -1) { - int index = 0; - for (int i = 0; i < nodes.length(); ++i, index += node_fields_count) { - nodes[i]->set_entry_index(index); - } - } -} - - void HeapSnapshotJSONSerializer::SerializeImpl() { - List<HeapEntry*>& nodes = *(snapshot_->entries()); - CalculateNodeIndexes(nodes); writer_->AddCharacter('{'); writer_->AddString("\"snapshot\":{"); SerializeSnapshot(); if (writer_->aborted()) return; writer_->AddString("},\n"); writer_->AddString("\"nodes\":["); - SerializeNodes(nodes); - if (writer_->aborted()) return; - writer_->AddString("],\n"); - writer_->AddString("\"edges\":["); - SerializeEdges(nodes); + SerializeNodes(); if (writer_->aborted()) return; writer_->AddString("],\n"); writer_->AddString("\"strings\":["); @@ -3778,43 +3464,45 @@ void HeapSnapshotJSONSerializer::SerializeImpl() { } -int HeapSnapshotJSONSerializer::GetStringId(const char* s) { - HashMap::Entry* cache_entry = strings_.Lookup( - const_cast<char*>(s), ObjectHash(s), true); - if (cache_entry->value == NULL) { - cache_entry->value = reinterpret_cast<void*>(next_string_id_++); +class HeapSnapshotJSONSerializerEnumerator { + public: + explicit HeapSnapshotJSONSerializerEnumerator(HeapSnapshotJSONSerializer* s) + : s_(s) { } - return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); + void Apply(HeapEntry** entry) { + s_->GetNodeId(*entry); + } + private: + HeapSnapshotJSONSerializer* s_; +}; + +void HeapSnapshotJSONSerializer::EnumerateNodes() { + GetNodeId(snapshot_->root()); // Make sure root gets the first id. + HeapSnapshotJSONSerializerEnumerator iter(this); + snapshot_->IterateEntries(&iter); } -// This function won't work correctly for MIN_INT but this is not -// a problem in case of heap snapshots serialization. -static int itoa(int value, const Vector<char>& buffer, int buffer_pos) { - if (value < 0) { - buffer[buffer_pos++] = '-'; - value = -value; +int HeapSnapshotJSONSerializer::GetNodeId(HeapEntry* entry) { + HashMap::Entry* cache_entry = nodes_.Lookup(entry, ObjectHash(entry), true); + if (cache_entry->value == NULL) { + cache_entry->value = reinterpret_cast<void*>(next_node_id_++); } + return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); +} - int number_of_digits = 0; - int t = value; - do { - ++number_of_digits; - } while (t /= 10); - buffer_pos += number_of_digits; - int result = buffer_pos; - do { - int last_digit = value % 10; - buffer[--buffer_pos] = '0' + last_digit; - value /= 10; - } while (value); - return result; +int HeapSnapshotJSONSerializer::GetStringId(const char* s) { + HashMap::Entry* cache_entry = strings_.Lookup( + const_cast<char*>(s), ObjectHash(s), true); + if (cache_entry->value == NULL) { + cache_entry->value = reinterpret_cast<void*>(next_string_id_++); + } + return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); } -void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, - bool first_edge) { +void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { // The buffer needs space for 3 ints, 3 commas and \0 static const int kBufferSize = MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT @@ -3823,72 +3511,125 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, || edge->type() == HeapGraphEdge::kHidden || edge->type() == HeapGraphEdge::kWeak ? edge->index() : GetStringId(edge->name()); - int buffer_pos = 0; - if (!first_edge) { - buffer[buffer_pos++] = ','; - } - buffer_pos = itoa(edge->type(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(edge_name_or_index, buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(edge->to()->entry_index(), buffer, buffer_pos); - buffer[buffer_pos++] = '\0'; + STATIC_CHECK(sizeof(int) == sizeof(edge->type())); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(edge_name_or_index)); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(edge->to()))); // NOLINT + int result = OS::SNPrintF(buffer, ",%d,%d,%d", + edge->type(), edge_name_or_index, GetNodeId(edge->to())); + USE(result); + ASSERT(result != -1); writer_->AddString(buffer.start()); } -void HeapSnapshotJSONSerializer::SerializeEdges(const List<HeapEntry*>& nodes) { - bool first_edge = true; - for (int i = 0; i < nodes.length(); ++i) { - HeapEntry* entry = nodes[i]; - Vector<HeapGraphEdge> children = entry->children(); - for (int j = 0; j < children.length(); ++j) { - SerializeEdge(&children[j], first_edge); - first_edge = false; - if (writer_->aborted()) return; - } - } -} - - -void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry, - int edges_index) { +void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { // The buffer needs space for 6 ints, 1 uint32_t, 7 commas, \n and \0 static const int kBufferSize = 6 * MaxDecimalDigitsIn<sizeof(int)>::kSigned // NOLINT + MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT + 7 + 1 + 1; EmbeddedVector<char, kBufferSize> buffer; - int buffer_pos = 0; - buffer[buffer_pos++] = '\n'; - if (entry->entry_index() != 0) { - buffer[buffer_pos++] = ','; - } - buffer_pos = itoa(entry->type(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(GetStringId(entry->name()), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(entry->id(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(entry->self_size(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(entry->retained_size(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(entry->dominator()->entry_index(), buffer, buffer_pos); - buffer[buffer_pos++] = ','; - buffer_pos = itoa(edges_index, buffer, buffer_pos); - buffer[buffer_pos++] = '\0'; + Vector<HeapGraphEdge> children = entry->children(); + STATIC_CHECK(sizeof(int) == sizeof(entry->type())); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(GetStringId(entry->name()))); // NOLINT + STATIC_CHECK(sizeof(unsigned) == sizeof(entry->id())); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(entry->self_size())); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(entry->retained_size())); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(entry->dominator()))); // NOLINT + STATIC_CHECK(sizeof(int) == sizeof(children.length())); // NOLINT + int result = OS::SNPrintF(buffer, "\n,%d,%d,%u,%d,%d,%d,%d", + entry->type(), + GetStringId(entry->name()), + entry->id(), + entry->self_size(), + entry->retained_size(), + GetNodeId(entry->dominator()), + children.length()); + USE(result); + ASSERT(result != -1); writer_->AddString(buffer.start()); + for (int i = 0; i < children.length(); ++i) { + SerializeEdge(&children[i]); + if (writer_->aborted()) return; + } } -void HeapSnapshotJSONSerializer::SerializeNodes(const List<HeapEntry*>& nodes) { +void HeapSnapshotJSONSerializer::SerializeNodes() { + // The first (zero) item of nodes array is an object describing node + // serialization layout. We use a set of macros to improve + // readability. +#define JSON_A(s) "["s"]" +#define JSON_O(s) "{"s"}" +#define JSON_S(s) "\""s"\"" + writer_->AddString(JSON_O( + JSON_S("fields") ":" JSON_A( + JSON_S("type") + "," JSON_S("name") + "," JSON_S("id") + "," JSON_S("self_size") + "," JSON_S("retained_size") + "," JSON_S("dominator") + "," JSON_S("children_count") + "," JSON_S("children")) + "," JSON_S("types") ":" JSON_A( + JSON_A( + JSON_S("hidden") + "," JSON_S("array") + "," JSON_S("string") + "," JSON_S("object") + "," JSON_S("code") + "," JSON_S("closure") + "," JSON_S("regexp") + "," JSON_S("number") + "," JSON_S("native") + "," JSON_S("synthetic")) + "," JSON_S("string") + "," JSON_S("number") + "," JSON_S("number") + "," JSON_S("number") + "," JSON_S("number") + "," JSON_S("number") + "," JSON_O( + JSON_S("fields") ":" JSON_A( + JSON_S("type") + "," JSON_S("name_or_index") + "," JSON_S("to_node")) + "," JSON_S("types") ":" JSON_A( + JSON_A( + JSON_S("context") + "," JSON_S("element") + "," JSON_S("property") + "," JSON_S("internal") + "," JSON_S("hidden") + "," JSON_S("shortcut") + "," JSON_S("weak")) + "," JSON_S("string_or_number") + "," JSON_S("node")))))); +#undef JSON_S +#undef JSON_O +#undef JSON_A + + const int node_fields_count = 7; + // type,name,id,self_size,retained_size,dominator,children_count. const int edge_fields_count = 3; // type,name|index,to_node. - int edges_index = 0; - for (int i = 0; i < nodes.length(); ++i) { - HeapEntry* entry = nodes[i]; - SerializeNode(entry, edges_index); - edges_index += entry->children().length() * edge_fields_count; + List<HashMap::Entry*> sorted_nodes; + SortHashMap(&nodes_, &sorted_nodes); + // Rewrite node ids, so they refer to actual array positions. + if (sorted_nodes.length() > 1) { + // Nodes start from array index 1. + int prev_value = 1; + sorted_nodes[0]->value = reinterpret_cast<void*>(prev_value); + for (int i = 1; i < sorted_nodes.length(); ++i) { + HeapEntry* prev_heap_entry = + reinterpret_cast<HeapEntry*>(sorted_nodes[i-1]->key); + prev_value += node_fields_count + + prev_heap_entry->children().length() * edge_fields_count; + sorted_nodes[i]->value = reinterpret_cast<void*>(prev_value); + } + } + for (int i = 0; i < sorted_nodes.length(); ++i) { + SerializeNode(reinterpret_cast<HeapEntry*>(sorted_nodes[i]->key)); if (writer_->aborted()) return; } } @@ -3900,61 +3641,6 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() { writer_->AddString("\""); writer_->AddString(",\"uid\":"); writer_->AddNumber(snapshot_->uid()); - writer_->AddString(",\"meta\":"); - // The object describing node serialization layout. - // We use a set of macros to improve readability. -#define JSON_A(s) "["s"]" -#define JSON_O(s) "{"s"}" -#define JSON_S(s) "\""s"\"" - writer_->AddString(JSON_O( - JSON_S("node_fields") ":" JSON_A( - JSON_S("type") "," - JSON_S("name") "," - JSON_S("id") "," - JSON_S("self_size") "," - JSON_S("retained_size") "," - JSON_S("dominator") "," - JSON_S("edges_index")) "," - JSON_S("node_types") ":" JSON_A( - JSON_A( - JSON_S("hidden") "," - JSON_S("array") "," - JSON_S("string") "," - JSON_S("object") "," - JSON_S("code") "," - JSON_S("closure") "," - JSON_S("regexp") "," - JSON_S("number") "," - JSON_S("native") "," - JSON_S("synthetic")) "," - JSON_S("string") "," - JSON_S("number") "," - JSON_S("number") "," - JSON_S("number") "," - JSON_S("number") "," - JSON_S("number")) "," - JSON_S("edge_fields") ":" JSON_A( - JSON_S("type") "," - JSON_S("name_or_index") "," - JSON_S("to_node")) "," - JSON_S("edge_types") ":" JSON_A( - JSON_A( - JSON_S("context") "," - JSON_S("element") "," - JSON_S("property") "," - JSON_S("internal") "," - JSON_S("hidden") "," - JSON_S("shortcut") "," - JSON_S("weak")) "," - JSON_S("string_or_number") "," - JSON_S("node")))); -#undef JSON_S -#undef JSON_O -#undef JSON_A - writer_->AddString(",\"node_count\":"); - writer_->AddNumber(snapshot_->entries()->length()); - writer_->AddString(",\"edge_count\":"); - writer_->AddNumber(snapshot_->number_of_edges()); } diff --git a/deps/v8/src/profile-generator.h b/deps/v8/src/profile-generator.h index e04ddbf3e2..d9a1319b87 100644 --- a/deps/v8/src/profile-generator.h +++ b/deps/v8/src/profile-generator.h @@ -35,6 +35,8 @@ namespace v8 { namespace internal { +typedef uint32_t SnapshotObjectId; + class TokenEnumerator { public: TokenEnumerator(); @@ -464,20 +466,21 @@ class HeapGraphEdge BASE_EMBEDDED { void Init(int child_index, Type type, int index, HeapEntry* to); void Init(int child_index, int index, HeapEntry* to); - Type type() const { return static_cast<Type>(type_); } - int index() const { + Type type() { return static_cast<Type>(type_); } + int index() { ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); return index_; } - const char* name() const { + const char* name() { ASSERT(type_ == kContextVariable || type_ == kProperty || type_ == kInternal || type_ == kShortcut); return name_; } - HeapEntry* to() const { return to_; } - INLINE(HeapEntry* from() const); + HeapEntry* to() { return to_; } + + HeapEntry* From(); private: int child_index_ : 29; @@ -548,8 +551,6 @@ class HeapEntry BASE_EMBEDDED { void set_retained_size(int value) { retained_size_ = value; } int ordered_index() { return ordered_index_; } void set_ordered_index(int value) { ordered_index_ = value; } - int entry_index() { return entry_index_; } - void set_entry_index(int value) { entry_index_ = value; } Vector<HeapGraphEdge> children() { return Vector<HeapGraphEdge>(children_arr(), children_count_); } @@ -563,8 +564,6 @@ class HeapEntry BASE_EMBEDDED { void clear_paint() { painted_ = false; } bool painted() { return painted_; } void paint() { painted_ = true; } - bool user_reachable() { return user_reachable_; } - void set_user_reachable() { user_reachable_ = true; } void SetIndexedReference(HeapGraphEdge::Type type, int child_index, @@ -601,16 +600,14 @@ class HeapEntry BASE_EMBEDDED { const char* TypeAsString(); unsigned painted_: 1; - unsigned user_reachable_: 1; unsigned type_: 4; - int children_count_: 26; + int children_count_: 27; int retainers_count_; int self_size_; union { int ordered_index_; // Used during dominator tree building. int retained_size_; // At that moment, there is no retained size yet. }; - int entry_index_; SnapshotObjectId id_; HeapEntry* dominator_; HeapSnapshot* snapshot_; @@ -650,11 +647,6 @@ class HeapSnapshot { HeapEntry* gc_subroot(int index) { return gc_subroot_entries_[index]; } List<HeapEntry*>* entries() { return &entries_; } size_t raw_entries_size() { return raw_entries_size_; } - int number_of_edges() { return number_of_edges_; } - void RememberLastJSObjectId(); - SnapshotObjectId max_snapshot_js_object_id() const { - return max_snapshot_js_object_id_; - } void AllocateEntries( int entries_count, int children_count, int retainers_count); @@ -673,6 +665,8 @@ class HeapSnapshot { void ClearPaint(); HeapEntry* GetEntryById(SnapshotObjectId id); List<HeapEntry*>* GetSortedEntriesList(); + template<class Visitor> + void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); } void SetDominatorsToSelf(); void Print(int max_depth); @@ -691,10 +685,8 @@ class HeapSnapshot { HeapEntry* gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags]; char* raw_entries_; List<HeapEntry*> entries_; - List<HeapEntry*> sorted_entries_; + bool entries_sorted_; size_t raw_entries_size_; - int number_of_edges_; - SnapshotObjectId max_snapshot_js_object_id_; friend class HeapSnapshotTester; @@ -705,17 +697,11 @@ class HeapSnapshot { class HeapObjectsMap { public: HeapObjectsMap(); + ~HeapObjectsMap(); void SnapshotGenerationFinished(); - SnapshotObjectId FindEntry(Address addr); - SnapshotObjectId FindOrAddEntry(Address addr, unsigned int size); + SnapshotObjectId FindObject(Address addr); void MoveObject(Address from, Address to); - SnapshotObjectId last_assigned_id() const { - return next_id_ - kObjectIdStep; - } - - void StopHeapObjectsTracking(); - void PushHeapObjectsStats(OutputStream* stream); static SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info); static inline SnapshotObjectId GetNthGcSubrootId(int delta); @@ -729,23 +715,16 @@ class HeapObjectsMap { private: struct EntryInfo { - EntryInfo(SnapshotObjectId id, Address addr, unsigned int size) - : id(id), addr(addr), size(size), accessed(true) { } - EntryInfo(SnapshotObjectId id, Address addr, unsigned int size, bool accessed) - : id(id), addr(addr), size(size), accessed(accessed) { } + explicit EntryInfo(SnapshotObjectId id) : id(id), accessed(true) { } + EntryInfo(SnapshotObjectId id, bool accessed) + : id(id), + accessed(accessed) { } SnapshotObjectId id; - Address addr; - unsigned int size; bool accessed; }; - struct TimeInterval { - explicit TimeInterval(SnapshotObjectId id) : id(id), size(0), count(0) { } - SnapshotObjectId id; - uint32_t size; - uint32_t count; - }; - void UpdateHeapObjectsMap(); + void AddEntry(Address addr, SnapshotObjectId id); + SnapshotObjectId FindEntry(Address addr); void RemoveDeadEntries(); static bool AddressesMatch(void* key1, void* key2) { @@ -758,10 +737,10 @@ class HeapObjectsMap { v8::internal::kZeroHashSeed); } + bool initial_fill_mode_; SnapshotObjectId next_id_; HashMap entries_map_; - List<EntryInfo> entries_; - List<TimeInterval> time_intervals_; + List<EntryInfo>* entries_; DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap); }; @@ -773,11 +752,6 @@ class HeapSnapshotsCollection { ~HeapSnapshotsCollection(); bool is_tracking_objects() { return is_tracking_objects_; } - void PushHeapObjectsStats(OutputStream* stream) { - return ids_.PushHeapObjectsStats(stream); - } - void StartHeapObjectsTracking() { is_tracking_objects_ = true; } - void StopHeapObjectsTracking() { ids_.StopHeapObjectsTracking(); } HeapSnapshot* NewSnapshot( HeapSnapshot::Type type, const char* name, unsigned uid); @@ -789,17 +763,9 @@ class HeapSnapshotsCollection { StringsStorage* names() { return &names_; } TokenEnumerator* token_enumerator() { return token_enumerator_; } - SnapshotObjectId FindObjectId(Address object_addr) { - return ids_.FindEntry(object_addr); - } - SnapshotObjectId GetObjectId(Address object_addr, int object_size) { - return ids_.FindOrAddEntry(object_addr, object_size); - } + SnapshotObjectId GetObjectId(Address addr) { return ids_.FindObject(addr); } Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id); void ObjectMoveEvent(Address from, Address to) { ids_.MoveObject(from, to); } - SnapshotObjectId last_assigned_id() const { - return ids_.last_assigned_id(); - } private: INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) { @@ -840,7 +806,7 @@ class HeapEntriesMap { HeapEntriesMap(); ~HeapEntriesMap(); - void AllocateEntries(HeapThing root_object); + void AllocateEntries(); HeapEntry* Map(HeapThing thing); void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry); void CountReference(HeapThing from, HeapThing to, @@ -867,8 +833,6 @@ class HeapEntriesMap { int retainers_count; }; - static inline void AllocateHeapEntryForMapEntry(HashMap::Entry* map_entry); - static uint32_t Hash(HeapThing thing) { return ComputeIntegerHash( static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)), @@ -897,7 +861,6 @@ class HeapObjectsSet { void Insert(Object* obj); const char* GetTag(Object* obj); void SetTag(Object* obj, const char* tag); - bool is_empty() const { return entries_.occupancy() == 0; } private: HashMap entries_; @@ -975,25 +938,11 @@ class V8HeapExplorer : public HeapEntriesAllocator { int children_count, int retainers_count); const char* GetSystemEntryName(HeapObject* object); - void ExtractReferences(HeapObject* obj); - void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy); - void ExtractJSObjectReferences(HeapEntry* entry, JSObject* js_obj); - void ExtractStringReferences(HeapEntry* entry, String* obj); - void ExtractContextReferences(HeapEntry* entry, Context* context); - void ExtractMapReferences(HeapEntry* entry, Map* map); - void ExtractSharedFunctionInfoReferences(HeapEntry* entry, - SharedFunctionInfo* shared); - void ExtractScriptReferences(HeapEntry* entry, Script* script); - void ExtractCodeCacheReferences(HeapEntry* entry, CodeCache* code_cache); - void ExtractCodeReferences(HeapEntry* entry, Code* code); - void ExtractJSGlobalPropertyCellReferences(HeapEntry* entry, - JSGlobalPropertyCell* cell); void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry); - bool IsEssentialObject(Object* object); void SetClosureReference(HeapObject* parent_obj, HeapEntry* parent, String* reference_name, @@ -1035,12 +984,11 @@ class V8HeapExplorer : public HeapEntriesAllocator { HeapEntry* parent, String* reference_name, Object* child); - void SetUserGlobalReference(Object* window); + void SetRootShortcutReference(Object* child); void SetRootGcRootsReference(); void SetGcRootsReference(VisitorSynchronization::SyncTag tag); void SetGcSubrootReference( VisitorSynchronization::SyncTag tag, bool is_weak, Object* child); - const char* GetStrongGcSubrootName(Object* object); void SetObjectName(HeapObject* object); void TagObject(Object* obj, const char* tag); @@ -1055,7 +1003,6 @@ class V8HeapExplorer : public HeapEntriesAllocator { SnapshottingProgressReportingInterface* progress_; SnapshotFillerInterface* filler_; HeapObjectsSet objects_tags_; - HeapObjectsSet strong_gc_subroot_names_; static HeapObject* const kGcRootsObject; static HeapObject* const kFirstGcSubrootObject; @@ -1141,9 +1088,7 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { bool CalculateRetainedSizes(); bool CountEntriesAndReferences(); bool FillReferences(); - void FillPostorderIndexes(Vector<HeapEntry*>* entries); - bool IsUserGlobalReference(const HeapGraphEdge& edge); - void MarkUserReachableObjects(); + void FillReversePostorderIndexes(Vector<HeapEntry*>* entries); void ProgressStep(); bool ProgressReport(bool force = false); bool SetEntriesDominators(); @@ -1168,6 +1113,7 @@ class HeapSnapshotJSONSerializer { public: explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot) : snapshot_(snapshot), + nodes_(ObjectsMatch), strings_(ObjectsMatch), next_node_id_(1), next_string_id_(1), @@ -1186,14 +1132,14 @@ class HeapSnapshotJSONSerializer { v8::internal::kZeroHashSeed); } - void CalculateNodeIndexes(const List<HeapEntry*>& nodes); + void EnumerateNodes(); HeapSnapshot* CreateFakeSnapshot(); + int GetNodeId(HeapEntry* entry); int GetStringId(const char* s); - void SerializeEdge(HeapGraphEdge* edge, bool first_edge); - void SerializeEdges(const List<HeapEntry*>& nodes); + void SerializeEdge(HeapGraphEdge* edge); void SerializeImpl(); - void SerializeNode(HeapEntry* entry, int edges_index); - void SerializeNodes(const List<HeapEntry*>& nodes); + void SerializeNode(HeapEntry* entry); + void SerializeNodes(); void SerializeSnapshot(); void SerializeString(const unsigned char* s); void SerializeStrings(); @@ -1202,6 +1148,7 @@ class HeapSnapshotJSONSerializer { static const int kMaxSerializableSnapshotRawSize; HeapSnapshot* snapshot_; + HashMap nodes_; HashMap strings_; int next_node_id_; int next_string_id_; diff --git a/deps/v8/src/property.h b/deps/v8/src/property.h index ba5e3c8998..04f78b22d4 100644 --- a/deps/v8/src/property.h +++ b/deps/v8/src/property.h @@ -214,6 +214,13 @@ class LookupResult BASE_EMBEDDED { number_ = number; } + void DescriptorResult(JSObject* holder, Smi* details, int number) { + lookup_type_ = DESCRIPTOR_TYPE; + holder_ = holder; + details_ = PropertyDetails(details); + number_ = number; + } + void ConstantResult(JSObject* holder) { lookup_type_ = CONSTANT_TYPE; holder_ = holder; diff --git a/deps/v8/src/regexp-macro-assembler-irregexp-inl.h b/deps/v8/src/regexp-macro-assembler-irregexp-inl.h index a767ec0089..f2a4e851f7 100644 --- a/deps/v8/src/regexp-macro-assembler-irregexp-inl.h +++ b/deps/v8/src/regexp-macro-assembler-irregexp-inl.h @@ -62,16 +62,6 @@ void RegExpMacroAssemblerIrregexp::Emit16(uint32_t word) { } -void RegExpMacroAssemblerIrregexp::Emit8(uint32_t word) { - ASSERT(pc_ <= buffer_.length()); - if (pc_ == buffer_.length()) { - Expand(); - } - *reinterpret_cast<unsigned char*>(buffer_.start() + pc_) = word; - pc_ += 1; -} - - void RegExpMacroAssemblerIrregexp::Emit32(uint32_t word) { ASSERT(pc_ <= buffer_.length()); if (pc_ + 3 >= buffer_.length()) { diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.cc b/deps/v8/src/regexp-macro-assembler-irregexp.cc index aa67919c54..322efa1365 100644 --- a/deps/v8/src/regexp-macro-assembler-irregexp.cc +++ b/deps/v8/src/regexp-macro-assembler-irregexp.cc @@ -352,42 +352,6 @@ void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd( } -void RegExpMacroAssemblerIrregexp::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - Emit(BC_CHECK_CHAR_IN_RANGE, 0); - Emit16(from); - Emit16(to); - EmitOrLink(on_in_range); -} - - -void RegExpMacroAssemblerIrregexp::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0); - Emit16(from); - Emit16(to); - EmitOrLink(on_not_in_range); -} - - -void RegExpMacroAssemblerIrregexp::CheckBitInTable( - Handle<ByteArray> table, Label* on_bit_set) { - Emit(BC_CHECK_BIT_IN_TABLE, 0); - EmitOrLink(on_bit_set); - for (int i = 0; i < kTableSize; i += kBitsPerByte) { - int byte = 0; - for (int j = 0; j < kBitsPerByte; j++) { - if (table->get(i + j) != 0) byte |= 1 << j; - } - Emit8(byte); - } -} - - void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg, Label* on_not_equal) { ASSERT(start_reg >= 0); diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.h b/deps/v8/src/regexp-macro-assembler-irregexp.h index 25cb68de0b..262ead297c 100644 --- a/deps/v8/src/regexp-macro-assembler-irregexp.h +++ b/deps/v8/src/regexp-macro-assembler-irregexp.h @@ -93,13 +93,6 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler { uc16 minus, uc16 mask, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); virtual void CheckNotBackReference(int start_reg, Label* on_no_match); virtual void CheckNotBackReferenceIgnoreCase(int start_reg, Label* on_no_match); @@ -121,7 +114,6 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler { inline void EmitOrLink(Label* label); inline void Emit32(uint32_t x); inline void Emit16(uint32_t x); - inline void Emit8(uint32_t x); inline void Emit(uint32_t bc, uint32_t arg); // Bytecode buffer. int length(); diff --git a/deps/v8/src/regexp-macro-assembler-tracer.cc b/deps/v8/src/regexp-macro-assembler-tracer.cc index b7aeac48db..f8432784f2 100644 --- a/deps/v8/src/regexp-macro-assembler-tracer.cc +++ b/deps/v8/src/regexp-macro-assembler-tracer.cc @@ -198,55 +198,24 @@ void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset, } -class PrintablePrinter { - public: - explicit PrintablePrinter(uc16 character) : character_(character) { } - - const char* operator*() { - if (character_ >= ' ' && character_ <= '~') { - buffer_[0] = '('; - buffer_[1] = static_cast<char>(character_); - buffer_[2] = ')'; - buffer_[3] = '\0'; - } else { - buffer_[0] = '\0'; - } - return &buffer_[0]; - }; - - private: - uc16 character_; - char buffer_[4]; -}; - - void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) { - PrintablePrinter printable(limit); - PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n", - limit, - *printable, - LabelToInt(on_less)); + PrintF(" CheckCharacterLT(c='u%04x', label[%08x]);\n", + limit, LabelToInt(on_less)); assembler_->CheckCharacterLT(limit, on_less); } void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit, Label* on_greater) { - PrintablePrinter printable(limit); - PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n", - limit, - *printable, - LabelToInt(on_greater)); + PrintF(" CheckCharacterGT(c='u%04x', label[%08x]);\n", + limit, LabelToInt(on_greater)); assembler_->CheckCharacterGT(limit, on_greater); } void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) { - PrintablePrinter printable(c); - PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n", - c, - *printable, - LabelToInt(on_equal)); + PrintF(" CheckCharacter(c='u%04x', label[%08x]);\n", + c, LabelToInt(on_equal)); assembler_->CheckCharacter(c, on_equal); } @@ -265,11 +234,8 @@ void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) { void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c, Label* on_not_equal) { - PrintablePrinter printable(c); - PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n", - c, - *printable, - LabelToInt(on_not_equal)); + PrintF(" CheckNotCharacter(c='u%04x', label[%08x]);\n", + c, LabelToInt(on_not_equal)); assembler_->CheckNotCharacter(c, on_not_equal); } @@ -278,10 +244,8 @@ void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd( unsigned c, unsigned mask, Label* on_equal) { - PrintablePrinter printable(c); - PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n", + PrintF(" CheckCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n", c, - *printable, mask, LabelToInt(on_equal)); assembler_->CheckCharacterAfterAnd(c, mask, on_equal); @@ -292,10 +256,8 @@ void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd( unsigned c, unsigned mask, Label* on_not_equal) { - PrintablePrinter printable(c); - PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n", + PrintF(" CheckNotCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n", c, - *printable, mask, LabelToInt(on_not_equal)); assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal); @@ -307,7 +269,7 @@ void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd( uc16 minus, uc16 mask, Label* on_not_equal) { - PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, " + PrintF(" CheckNotCharacterAfterMinusAnd(c='u%04x', minus=%04x, mask=0x%04x, " "label[%08x]);\n", c, minus, @@ -317,53 +279,6 @@ void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd( } -void RegExpMacroAssemblerTracer::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - PrintablePrinter printable_from(from); - PrintablePrinter printable_to(to); - PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n", - from, - *printable_from, - to, - *printable_to, - LabelToInt(on_not_in_range)); - assembler_->CheckCharacterInRange(from, to, on_not_in_range); -} - - -void RegExpMacroAssemblerTracer::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - PrintablePrinter printable_from(from); - PrintablePrinter printable_to(to); - PrintF( - " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n", - from, - *printable_from, - to, - *printable_to, - LabelToInt(on_in_range)); - assembler_->CheckCharacterNotInRange(from, to, on_in_range); -} - - -void RegExpMacroAssemblerTracer::CheckBitInTable( - Handle<ByteArray> table, Label* on_bit_set) { - PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set)); - for (int i = 0; i < kTableSize; i++) { - PrintF("%c", table->get(i) != 0 ? 'X' : '.'); - if (i % 32 == 31 && i != kTableMask) { - PrintF("\n "); - } - } - PrintF(");\n"); - assembler_->CheckBitInTable(table, on_bit_set); -} - - void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg, Label* on_no_match) { PrintF(" CheckNotBackReference(register=%d, label[%08x]);\n", start_reg, @@ -399,7 +314,7 @@ void RegExpMacroAssemblerTracer::CheckCharacters(Vector<const uc16> str, PrintF(" %s(str=\"", check_end_of_string ? "CheckCharacters" : "CheckCharactersUnchecked"); for (int i = 0; i < str.length(); i++) { - PrintF("0x%04x", str[i]); + PrintF("u%04x", str[i]); } PrintF("\", cp_offset=%d, label[%08x])\n", cp_offset, LabelToInt(on_failure)); diff --git a/deps/v8/src/regexp-macro-assembler-tracer.h b/deps/v8/src/regexp-macro-assembler-tracer.h index 3fd4d8b39a..1cf0349d86 100644 --- a/deps/v8/src/regexp-macro-assembler-tracer.h +++ b/deps/v8/src/regexp-macro-assembler-tracer.h @@ -68,13 +68,6 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler { uc16 minus, uc16 and_with, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match); virtual void Fail(); diff --git a/deps/v8/src/regexp-macro-assembler.h b/deps/v8/src/regexp-macro-assembler.h index 85874358e5..0314c707c6 100644 --- a/deps/v8/src/regexp-macro-assembler.h +++ b/deps/v8/src/regexp-macro-assembler.h @@ -45,11 +45,6 @@ class RegExpMacroAssembler { static const int kMaxRegister = (1 << 16) - 1; static const int kMaxCPOffset = (1 << 15) - 1; static const int kMinCPOffset = -(1 << 15); - - static const int kTableSizeBits = 7; - static const int kTableSize = 1 << kTableSizeBits; - static const int kTableMask = kTableSize - 1; - enum IrregexpImplementation { kIA32Implementation, kARMImplementation, @@ -111,23 +106,12 @@ class RegExpMacroAssembler { virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, Label* on_not_equal) = 0; - // Subtract a constant from the current character, then and with the given + // Subtract a constant from the current character, then or with the given // constant and then check for a match with c. virtual void CheckNotCharacterAfterMinusAnd(uc16 c, uc16 minus, uc16 and_with, Label* on_not_equal) = 0; - virtual void CheckCharacterInRange(uc16 from, - uc16 to, // Both inclusive. - Label* on_in_range) = 0; - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, // Both inclusive. - Label* on_not_in_range) = 0; - - // The current character (modulus the kTableSize) is looked up in the byte - // array, and if the found byte is non-zero, we jump to the on_bit_set label. - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) = 0; - virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal) = 0; diff --git a/deps/v8/src/regexp.js b/deps/v8/src/regexp.js index a574f62bf6..eb617eae42 100644 --- a/deps/v8/src/regexp.js +++ b/deps/v8/src/regexp.js @@ -278,7 +278,11 @@ function TrimRegExp(regexp) { function RegExpToString() { - var result = '/' + this.source + '/'; + // If this.source is an empty string, output /(?:)/. + // http://bugzilla.mozilla.org/show_bug.cgi?id=225550 + // ecma_2/RegExp/properties-001.js. + var src = this.source ? this.source : '(?:)'; + var result = '/' + src + '/'; if (this.global) result += 'g'; if (this.ignoreCase) result += 'i'; if (this.multiline) result += 'm'; @@ -292,7 +296,7 @@ function RegExpToString() { // of the last successful match. function RegExpGetLastMatch() { if (lastMatchInfoOverride !== null) { - return OVERRIDE_MATCH(lastMatchInfoOverride); + return lastMatchInfoOverride[0]; } var regExpSubject = LAST_SUBJECT(lastMatchInfo); return SubString(regExpSubject, @@ -330,8 +334,8 @@ function RegExpGetLeftContext() { subject = LAST_SUBJECT(lastMatchInfo); } else { var override = lastMatchInfoOverride; - start_index = OVERRIDE_POS(override); - subject = OVERRIDE_SUBJECT(override); + start_index = override[override.length - 2]; + subject = override[override.length - 1]; } return SubString(subject, 0, start_index); } @@ -345,9 +349,9 @@ function RegExpGetRightContext() { subject = LAST_SUBJECT(lastMatchInfo); } else { var override = lastMatchInfoOverride; - subject = OVERRIDE_SUBJECT(override); - var match = OVERRIDE_MATCH(override); - start_index = OVERRIDE_POS(override) + match.length; + subject = override[override.length - 1]; + var pattern = override[override.length - 3]; + start_index = override[override.length - 2] + pattern.length; } return SubString(subject, start_index, subject.length); } @@ -359,9 +363,7 @@ function RegExpGetRightContext() { function RegExpMakeCaptureGetter(n) { return function() { if (lastMatchInfoOverride) { - if (n < lastMatchInfoOverride.length - 2) { - return OVERRIDE_CAPTURE(lastMatchInfoOverride, n); - } + if (n < lastMatchInfoOverride.length - 2) return lastMatchInfoOverride[n]; return ''; } var index = n * 2; diff --git a/deps/v8/src/rewriter.cc b/deps/v8/src/rewriter.cc index e58ddb417e..55f93ee0d7 100644 --- a/deps/v8/src/rewriter.cc +++ b/deps/v8/src/rewriter.cc @@ -111,7 +111,7 @@ void Processor::VisitBlock(Block* node) { void Processor::VisitExpressionStatement(ExpressionStatement* node) { // Rewrite : <x>; -> .result = <x>; - if (!is_set_ && !node->expression()->IsThrow()) { + if (!is_set_) { node->set_expression(SetResult(node->expression())); if (!in_try_) is_set_ = true; } diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc index 568e48e412..b06168a246 100644 --- a/deps/v8/src/runtime-profiler.cc +++ b/deps/v8/src/runtime-profiler.cc @@ -94,14 +94,12 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate) sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit), sampler_ticks_until_threshold_adjustment_( kSamplerTicksBetweenThresholdAdjustment), - sampler_window_position_(0), - any_ic_changed_(false), - code_generated_(false) { + sampler_window_position_(0) { ClearSampleBuffer(); } -void RuntimeProfiler::GlobalSetUp() { +void RuntimeProfiler::GlobalSetup() { ASSERT(!has_been_globally_set_up_); enabled_ = V8::UseCrankshaft() && FLAG_opt; #ifdef DEBUG @@ -181,10 +179,14 @@ void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) { // prepared to generate it, but we don't expect to have to. bool found_code = false; Code* stack_check_code = NULL; +#if defined(V8_TARGET_ARCH_IA32) || \ + defined(V8_TARGET_ARCH_ARM) || \ + defined(V8_TARGET_ARCH_MIPS) if (FLAG_count_based_interrupts) { InterruptStub interrupt_stub; found_code = interrupt_stub.FindCodeInCache(&stack_check_code); } else // NOLINT +#endif { // NOLINT StackCheckStub check_stub; found_code = check_stub.FindCodeInCache(&stack_check_code); @@ -313,6 +315,14 @@ void RuntimeProfiler::OptimizeNow() { // If no IC was patched since the last tick and this function is very // small, optimistically optimize it now. Optimize(function, "small function"); + } else if (!code_generated_ && + !any_ic_changed_ && + total_code_generated_ > 0 && + total_code_generated_ < 2000) { + // If no code was generated and no IC was patched since the last tick, + // but a little code has already been generated since last Reset(), + // then type info might already be stable and we can optimize now. + Optimize(function, "stable on startup"); } else { shared_code->set_profiler_ticks(ticks + 1); } @@ -333,6 +343,7 @@ void RuntimeProfiler::OptimizeNow() { } if (FLAG_watch_ic_patching) { any_ic_changed_ = false; + code_generated_ = false; } else { // !FLAG_watch_ic_patching // Add the collected functions as samples. It's important not to do // this as part of collecting them because this will interfere with @@ -345,7 +356,11 @@ void RuntimeProfiler::OptimizeNow() { void RuntimeProfiler::NotifyTick() { +#if defined(V8_TARGET_ARCH_IA32) || \ + defined(V8_TARGET_ARCH_ARM) || \ + defined(V8_TARGET_ARCH_MIPS) if (FLAG_count_based_interrupts) return; +#endif isolate_->stack_guard()->RequestRuntimeProfilerTick(); } @@ -362,7 +377,9 @@ void RuntimeProfiler::SetUp() { void RuntimeProfiler::Reset() { - if (!FLAG_watch_ic_patching) { + if (FLAG_watch_ic_patching) { + total_code_generated_ = 0; + } else { // !FLAG_watch_ic_patching sampler_threshold_ = kSamplerThresholdInit; sampler_threshold_size_factor_ = kSamplerThresholdSizeFactorInit; sampler_ticks_until_threshold_adjustment_ = diff --git a/deps/v8/src/runtime-profiler.h b/deps/v8/src/runtime-profiler.h index ab6cb378ea..e3388492cb 100644 --- a/deps/v8/src/runtime-profiler.h +++ b/deps/v8/src/runtime-profiler.h @@ -43,7 +43,7 @@ class RuntimeProfiler { public: explicit RuntimeProfiler(Isolate* isolate); - static void GlobalSetUp(); + static void GlobalSetup(); static inline bool IsEnabled() { ASSERT(has_been_globally_set_up_); @@ -63,6 +63,13 @@ class RuntimeProfiler { void NotifyICChanged() { any_ic_changed_ = true; } + void NotifyCodeGenerated(int generated_code_size) { + if (FLAG_watch_ic_patching) { + code_generated_ = true; + total_code_generated_ += generated_code_size; + } + } + // Rate limiting support. // VM thread interface. @@ -123,6 +130,7 @@ class RuntimeProfiler { bool any_ic_changed_; bool code_generated_; + int total_code_generated_; // Possible state values: // -1 => the profiler thread is waiting on the semaphore diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index 6163ca8fa3..5996b82673 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -1289,79 +1289,90 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { // We have to declare a global const property. To capture we only // assign to it when evaluating the assignment for "const x = // <expr>" the initial value is the hole. - bool is_var = value->IsUndefined(); - bool is_const = value->IsTheHole(); - bool is_function = value->IsSharedFunctionInfo(); - bool is_module = value->IsJSModule(); - ASSERT(is_var + is_const + is_function + is_module == 1); - - if (is_var || is_const) { + bool is_const_property = value->IsTheHole(); + bool is_function_declaration = false; + if (value->IsUndefined() || is_const_property) { // Lookup the property in the global object, and don't set the // value of the variable if the property is already there. - // Do the lookup locally only, see ES5 errata. LookupResult lookup(isolate); - if (FLAG_es52_globals) - global->LocalLookup(*name, &lookup); - else - global->Lookup(*name, &lookup); + global->Lookup(*name, &lookup); if (lookup.IsProperty()) { // We found an existing property. Unless it was an interceptor // that claims the property is absent, skip this declaration. - if (lookup.type() != INTERCEPTOR) continue; + if (lookup.type() != INTERCEPTOR) { + continue; + } PropertyAttributes attributes = global->GetPropertyAttribute(*name); - if (attributes != ABSENT) continue; + if (attributes != ABSENT) { + continue; + } // Fall-through and introduce the absent property by using // SetProperty. } - } else if (is_function) { + } else { + is_function_declaration = true; // Copy the function and update its context. Use it as value. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(value); Handle<JSFunction> function = - isolate->factory()->NewFunctionFromSharedFunctionInfo( - shared, context, TENURED); + isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, + context, + TENURED); value = function; } LookupResult lookup(isolate); global->LocalLookup(*name, &lookup); - // Compute the property attributes. According to ECMA-262, - // the property must be non-configurable except in eval. + // Compute the property attributes. According to ECMA-262, section + // 13, page 71, the property must be read-only and + // non-deletable. However, neither SpiderMonkey nor KJS creates the + // property as read-only, so we don't either. int attr = NONE; - bool is_eval = DeclareGlobalsEvalFlag::decode(flags); - if (!is_eval || is_module) { + if (!DeclareGlobalsEvalFlag::decode(flags)) { attr |= DONT_DELETE; } bool is_native = DeclareGlobalsNativeFlag::decode(flags); - if (is_const || is_module || (is_native && is_function)) { + if (is_const_property || (is_native && is_function_declaration)) { attr |= READ_ONLY; } LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); - if (!lookup.IsProperty() || is_function || is_module) { - // If the local property exists, check that we can reconfigure it - // as required for function declarations. - if (lookup.IsProperty() && lookup.IsDontDelete()) { - if (lookup.IsReadOnly() || lookup.IsDontEnum() || - lookup.type() == CALLBACKS) { - return ThrowRedeclarationError( - isolate, is_function ? "function" : "module", name); + // Safari does not allow the invocation of callback setters for + // function declarations. To mimic this behavior, we do not allow + // the invocation of setters for function values. This makes a + // difference for global functions with the same names as event + // handlers such as "function onload() {}". Firefox does call the + // onload setter in those case and Safari does not. We follow + // Safari for compatibility. + if (is_function_declaration) { + if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { + // Do not overwrite READ_ONLY properties. + if (lookup.GetAttributes() & READ_ONLY) { + if (language_mode != CLASSIC_MODE) { + Handle<Object> args[] = { name }; + return isolate->Throw(*isolate->factory()->NewTypeError( + "strict_cannot_assign", HandleVector(args, ARRAY_SIZE(args)))); + } + continue; } - // If the existing property is not configurable, keep its attributes. - attr = lookup.GetAttributes(); + // Do not change DONT_DELETE to false from true. + attr |= lookup.GetAttributes() & DONT_DELETE; } - // Define or redefine own property. - RETURN_IF_EMPTY_HANDLE(isolate, - JSObject::SetLocalPropertyIgnoreAttributes( - global, name, value, static_cast<PropertyAttributes>(attr))); + PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); + + RETURN_IF_EMPTY_HANDLE( + isolate, + JSObject::SetLocalPropertyIgnoreAttributes(global, name, value, + attributes)); } else { - // Do a [[Put]] on the existing (own) property. - RETURN_IF_EMPTY_HANDLE(isolate, - JSObject::SetProperty( - global, name, value, static_cast<PropertyAttributes>(attr), - language_mode == CLASSIC_MODE ? kNonStrictMode : kStrictMode)); + RETURN_IF_EMPTY_HANDLE( + isolate, + JSReceiver::SetProperty(global, name, value, + static_cast<PropertyAttributes>(attr), + language_mode == CLASSIC_MODE + ? kNonStrictMode : kStrictMode)); } } @@ -1394,8 +1405,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { if (attributes != ABSENT) { // The name was declared before; check for conflicting re-declarations. - // Note: this is actually inconsistent with what happens for globals (where - // we silently ignore such declarations). if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { // Functions are not read-only. ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); @@ -1458,14 +1467,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { return ThrowRedeclarationError(isolate, "const", name); } } - if (object->IsJSGlobalObject()) { - // Define own property on the global object. - RETURN_IF_EMPTY_HANDLE(isolate, - JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode)); - } else { - RETURN_IF_EMPTY_HANDLE(isolate, - JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); - } + RETURN_IF_EMPTY_HANDLE( + isolate, + JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); } return isolate->heap()->undefined_value(); @@ -1783,9 +1787,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) { ASSERT(args.length() == 5); CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_CHECKED(String, source, 1); - // If source is the empty string we set it to "(?:)" instead as - // suggested by ECMA-262, 5th, section 15.10.4.1. - if (source->length() == 0) source = isolate->heap()->query_colon_symbol(); Object* global = args[2]; if (!global->IsTrue()) global = isolate->heap()->false_value(); @@ -2100,7 +2101,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) { DescriptorArray* instance_desc = function->map()->instance_descriptors(); int index = instance_desc->Search(name); ASSERT(index != DescriptorArray::kNotFound); - PropertyDetails details = instance_desc->GetDetails(index); + PropertyDetails details(instance_desc->GetDetails(index)); CallbacksDescriptor new_desc(name, instance_desc->GetValue(index), static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), @@ -2885,79 +2886,12 @@ void FindStringIndicesDispatch(Isolate* isolate, } -// Two smis before and after the match, for very long strings. -const int kMaxBuilderEntriesPerRegExpMatch = 5; - - -static void SetLastMatchInfoNoCaptures(Handle<String> subject, - Handle<JSArray> last_match_info, - int match_start, - int match_end) { - // Fill last_match_info with a single capture. - last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead); - AssertNoAllocation no_gc; - FixedArray* elements = FixedArray::cast(last_match_info->elements()); - RegExpImpl::SetLastCaptureCount(elements, 2); - RegExpImpl::SetLastInput(elements, *subject); - RegExpImpl::SetLastSubject(elements, *subject); - RegExpImpl::SetCapture(elements, 0, match_start); - RegExpImpl::SetCapture(elements, 1, match_end); -} - - -template <typename SubjectChar, typename PatternChar> -static bool SearchStringMultiple(Isolate* isolate, - Vector<const SubjectChar> subject, - Vector<const PatternChar> pattern, - String* pattern_string, - FixedArrayBuilder* builder, - int* match_pos) { - int pos = *match_pos; - int subject_length = subject.length(); - int pattern_length = pattern.length(); - int max_search_start = subject_length - pattern_length; - StringSearch<PatternChar, SubjectChar> search(isolate, pattern); - while (pos <= max_search_start) { - if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) { - *match_pos = pos; - return false; - } - // Position of end of previous match. - int match_end = pos + pattern_length; - int new_pos = search.Search(subject, match_end); - if (new_pos >= 0) { - // A match. - if (new_pos > match_end) { - ReplacementStringBuilder::AddSubjectSlice(builder, - match_end, - new_pos); - } - pos = new_pos; - builder->Add(pattern_string); - } else { - break; - } - } - - if (pos < max_search_start) { - ReplacementStringBuilder::AddSubjectSlice(builder, - pos + pattern_length, - subject_length); - } - *match_pos = pos; - return true; -} - - - - template<typename ResultSeqString> -MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( +MUST_USE_RESULT static MaybeObject* StringReplaceStringWithString( Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, - Handle<String> replacement, - Handle<JSArray> last_match_info) { + Handle<String> replacement) { ASSERT(subject->IsFlat()); ASSERT(replacement->IsFlat()); @@ -3016,12 +2950,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString( subject_pos, subject_len); } - - SetLastMatchInfoNoCaptures(subject, - last_match_info, - indices.at(matches - 1), - indices.at(matches - 1) + pattern_len); - return *result; } @@ -3070,19 +2998,11 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( compiled_replacement.simple_hint()) { if (subject_handle->HasOnlyAsciiChars() && replacement_handle->HasOnlyAsciiChars()) { - return StringReplaceAtomRegExpWithString<SeqAsciiString>( - isolate, - subject_handle, - regexp_handle, - replacement_handle, - last_match_info_handle); + return StringReplaceStringWithString<SeqAsciiString>( + isolate, subject_handle, regexp_handle, replacement_handle); } else { - return StringReplaceAtomRegExpWithString<SeqTwoByteString>( - isolate, - subject_handle, - regexp_handle, - replacement_handle, - last_match_info_handle); + return StringReplaceStringWithString<SeqTwoByteString>( + isolate, subject_handle, regexp_handle, replacement_handle); } } @@ -3171,29 +3091,21 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( Handle<String> subject_handle(subject); Handle<JSRegExp> regexp_handle(regexp); - Handle<JSArray> last_match_info_handle(last_match_info); // Shortcut for simple non-regexp global replacements if (regexp_handle->GetFlags().is_global() && regexp_handle->TypeTag() == JSRegExp::ATOM) { Handle<String> empty_string_handle(HEAP->empty_string()); if (subject_handle->HasOnlyAsciiChars()) { - return StringReplaceAtomRegExpWithString<SeqAsciiString>( - isolate, - subject_handle, - regexp_handle, - empty_string_handle, - last_match_info_handle); + return StringReplaceStringWithString<SeqAsciiString>( + isolate, subject_handle, regexp_handle, empty_string_handle); } else { - return StringReplaceAtomRegExpWithString<SeqTwoByteString>( - isolate, - subject_handle, - regexp_handle, - empty_string_handle, - last_match_info_handle); + return StringReplaceStringWithString<SeqTwoByteString>( + isolate, subject_handle, regexp_handle, empty_string_handle); } } + Handle<JSArray> last_match_info_handle(last_match_info); Handle<Object> match = RegExpImpl::Exec(regexp_handle, subject_handle, 0, @@ -3213,10 +3125,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( end = RegExpImpl::GetCapture(match_info_array, 1); } - bool global = regexp_handle->GetFlags().is_global(); - - if (start == end && !global) return *subject_handle; - int length = subject_handle->length(); int new_length = length - (end - start); if (new_length == 0) { @@ -3232,7 +3140,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( } // If the regexp isn't global, only match once. - if (!global) { + if (!regexp_handle->GetFlags().is_global()) { if (start > 0) { String::WriteToFlat(*subject_handle, answer->GetChars(), @@ -3731,6 +3639,70 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) { } +// Two smis before and after the match, for very long strings. +const int kMaxBuilderEntriesPerRegExpMatch = 5; + + +static void SetLastMatchInfoNoCaptures(Handle<String> subject, + Handle<JSArray> last_match_info, + int match_start, + int match_end) { + // Fill last_match_info with a single capture. + last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead); + AssertNoAllocation no_gc; + FixedArray* elements = FixedArray::cast(last_match_info->elements()); + RegExpImpl::SetLastCaptureCount(elements, 2); + RegExpImpl::SetLastInput(elements, *subject); + RegExpImpl::SetLastSubject(elements, *subject); + RegExpImpl::SetCapture(elements, 0, match_start); + RegExpImpl::SetCapture(elements, 1, match_end); +} + + +template <typename SubjectChar, typename PatternChar> +static bool SearchStringMultiple(Isolate* isolate, + Vector<const SubjectChar> subject, + Vector<const PatternChar> pattern, + String* pattern_string, + FixedArrayBuilder* builder, + int* match_pos) { + int pos = *match_pos; + int subject_length = subject.length(); + int pattern_length = pattern.length(); + int max_search_start = subject_length - pattern_length; + StringSearch<PatternChar, SubjectChar> search(isolate, pattern); + while (pos <= max_search_start) { + if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) { + *match_pos = pos; + return false; + } + // Position of end of previous match. + int match_end = pos + pattern_length; + int new_pos = search.Search(subject, match_end); + if (new_pos >= 0) { + // A match. + if (new_pos > match_end) { + ReplacementStringBuilder::AddSubjectSlice(builder, + match_end, + new_pos); + } + pos = new_pos; + builder->Add(pattern_string); + } else { + break; + } + } + + if (pos < max_search_start) { + ReplacementStringBuilder::AddSubjectSlice(builder, + pos + pattern_length, + subject_length); + } + *match_pos = pos; + return true; +} + + static bool SearchStringMultiple(Isolate* isolate, Handle<String> subject, Handle<String> pattern, @@ -3870,8 +3842,6 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple( } -// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain -// separate last match info. See comment on that function. static RegExpImpl::IrregexpResult SearchRegExpMultiple( Isolate* isolate, Handle<String> subject, @@ -3900,6 +3870,10 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( // End of previous match. Differs from pos if match was empty. int match_end = 0; if (result == RegExpImpl::RE_SUCCESS) { + // Need to keep a copy of the previous match for creating last_match_info + // at the end, so we have two vectors that we swap between. + OffsetsVector registers2(required_registers, isolate); + Vector<int> prev_register_vector(registers2.vector(), registers2.length()); bool first = true; do { int match_start = register_vector[0]; @@ -3952,6 +3926,11 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( elements->set(capture_count + 2, *subject); builder->Add(*isolate->factory()->NewJSArrayWithElements(elements)); } + // Swap register vectors, so the last successful match is in + // prev_register_vector. + Vector<int32_t> tmp = prev_register_vector; + prev_register_vector = register_vector; + register_vector = tmp; if (match_end > match_start) { pos = match_end; @@ -3983,12 +3962,12 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( last_match_array->EnsureSize(last_match_array_size); AssertNoAllocation no_gc; FixedArray* elements = FixedArray::cast(last_match_array->elements()); - // We have to set this even though the rest of the last match array is - // ignored. RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count); - // These are also read without consulting the override. RegExpImpl::SetLastSubject(elements, *subject); RegExpImpl::SetLastInput(elements, *subject); + for (int i = 0; i < last_match_capture_count; i++) { + RegExpImpl::SetCapture(elements, i, prev_register_vector[i]); + } return RegExpImpl::RE_SUCCESS; } } @@ -3997,9 +3976,6 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple( } -// This is only called for StringReplaceGlobalRegExpWithFunction. This sets -// lastMatchInfoOverride to maintain the last match info, so we don't need to -// set any other last match array info. RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { ASSERT(args.length() == 4); HandleScope handles(isolate); @@ -4693,7 +4669,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { HandleScope scope; Object* raw_boilerplate_object = literals->get(literal_index); - Handle<JSArray> boilerplate(JSArray::cast(raw_boilerplate_object)); + Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); #if DEBUG ElementsKind elements_kind = object->GetElementsKind(); #endif @@ -4704,59 +4680,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { if (value->IsNumber()) { ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); - if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), - FAST_DOUBLE_ELEMENTS)) { - JSObject::TransitionElementsKind(boilerplate, FAST_DOUBLE_ELEMENTS); - } + JSObject::TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS); ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); - FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); + FixedDoubleArray* double_array = + FixedDoubleArray::cast(object->elements()); HeapNumber* number = HeapNumber::cast(*value); double_array->set(store_index, number->Number()); } else { ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || elements_kind == FAST_DOUBLE_ELEMENTS); JSObject::TransitionElementsKind(object, FAST_ELEMENTS); - if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), - FAST_ELEMENTS)) { - JSObject::TransitionElementsKind(boilerplate, FAST_ELEMENTS); - } - FixedArray* object_array = FixedArray::cast(object->elements()); + JSObject::TransitionElementsKind(boilerplate_object, FAST_ELEMENTS); + FixedArray* object_array = + FixedArray::cast(object->elements()); object_array->set(store_index, *value); } return *object; } -// Check whether debugger and is about to step into the callback that is passed -// to a built-in function such as Array.forEach. -RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) { - if (!isolate->IsDebuggerActive()) return isolate->heap()->false_value(); - CONVERT_ARG_CHECKED(Object, callback, 0); - // We do not step into the callback if it's a builtin or not even a function. - if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) { - return isolate->heap()->false_value(); - } - return isolate->heap()->true_value(); -} - - -// Set one shot breakpoints for the callback function that is passed to a -// built-in function such as Array.forEach to enable stepping into the callback. -RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) { - Debug* debug = isolate->debug(); - if (!debug->IsStepping()) return NULL; - CONVERT_ARG_CHECKED(Object, callback, 0); - HandleScope scope(isolate); - Handle<SharedFunctionInfo> shared_info(JSFunction::cast(callback)->shared()); - // When leaving the callback, step out has been activated, but not performed - // if we do not leave the builtin. To be able to step into the callback - // again, we need to clear the step out at this point. - debug->ClearStepOut(); - debug->FloodWithOneShot(shared_info); - return NULL; -} - - // Set a local property, even if it is READ_ONLY. If the property does not // exist, it will be added with attributes NONE. RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { @@ -8180,14 +8122,6 @@ static void MaterializeArgumentsObjectInFrame(Isolate* isolate, ASSERT(*arguments != isolate->heap()->undefined_value()); } frame->SetExpression(i, *arguments); - if (FLAG_trace_deopt) { - PrintF("Materializing arguments object for frame %p - %p: %p ", - reinterpret_cast<void*>(frame->sp()), - reinterpret_cast<void*>(frame->fp()), - reinterpret_cast<void*>(*arguments)); - arguments->ShortPrint(); - PrintF("\n"); - } } } } @@ -8316,13 +8250,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) { if (!V8::UseCrankshaft()) { return Smi::FromInt(4); // 4 == "never". } - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); if (FLAG_always_opt) { - // We may have always opt, but that is more best-effort than a real - // promise, so we still say "no" if it is not optimized. - return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always". - : Smi::FromInt(2); // 2 == "no". + return Smi::FromInt(3); // 3 == "always". } + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". : Smi::FromInt(2); // 2 == "no". } @@ -8426,10 +8357,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { PrintF("]\n"); } Handle<Code> check_code; +#if defined(V8_TARGET_ARCH_IA32) || \ + defined(V8_TARGET_ARCH_ARM) || \ + defined(V8_TARGET_ARCH_MIPS) if (FLAG_count_based_interrupts) { InterruptStub interrupt_stub; check_code = interrupt_stub.GetCode(); } else // NOLINT +#endif { // NOLINT StackCheckStub check_stub; check_code = check_stub.GetCode(); @@ -8668,25 +8603,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) { } -RUNTIME_FUNCTION(MaybeObject*, Runtime_PushModuleContext) { - NoHandleAllocation ha; - ASSERT(args.length() == 2); - CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 0); - CONVERT_ARG_HANDLE_CHECKED(JSModule, instance, 1); - - Context* context; - MaybeObject* maybe_context = - isolate->heap()->AllocateModuleContext(isolate->context(), - scope_info); - if (!maybe_context->To(&context)) return maybe_context; - // Also initialize the context slot of the instance object. - instance->set_context(context); - isolate->set_context(context); - - return context; -} - - RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { HandleScope scope(isolate); ASSERT(args.length() == 2); @@ -10988,10 +10904,10 @@ static Handle<JSObject> MaterializeModuleScope( } -// Iterate over the actual scopes visible from a stack frame or from a closure. -// The iteration proceeds from the innermost visible nested scope outwards. -// All scopes are backed by an actual context except the local scope, -// which is inserted "artificially" in the context chain. +// Iterate over the actual scopes visible from a stack frame. The iteration +// proceeds from the innermost visible nested scope outwards. All scopes are +// backed by an actual context except the local scope, which is inserted +// "artificially" in the context chain. class ScopeIterator { public: enum ScopeType { @@ -11092,18 +11008,6 @@ class ScopeIterator { } } - ScopeIterator(Isolate* isolate, - Handle<JSFunction> function) - : isolate_(isolate), - frame_(NULL), - inlined_jsframe_index_(0), - function_(function), - context_(function->context()) { - if (function->IsBuiltin()) { - context_ = Handle<Context>(); - } - } - // More scopes? bool Done() { return context_.is_null(); } @@ -11324,22 +11228,6 @@ static const int kScopeDetailsTypeIndex = 0; static const int kScopeDetailsObjectIndex = 1; static const int kScopeDetailsSize = 2; - -static MaybeObject* MaterializeScopeDetails(Isolate* isolate, - ScopeIterator* it) { - // Calculate the size of the result. - int details_size = kScopeDetailsSize; - Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); - - // Fill in scope details. - details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); - Handle<JSObject> scope_object = it->ScopeObject(); - RETURN_IF_EMPTY_HANDLE(isolate, scope_object); - details->set(kScopeDetailsObjectIndex, *scope_object); - - return *isolate->factory()->NewJSArrayWithElements(details); -} - // Return an array with scope details // args[0]: number: break id // args[1]: number: frame index @@ -11377,46 +11265,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) { if (it.Done()) { return isolate->heap()->undefined_value(); } - return MaterializeScopeDetails(isolate, &it); -} - - -RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) { - HandleScope scope(isolate); - ASSERT(args.length() == 1); - - // Check arguments. - CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); - - // Count the visible scopes. - int n = 0; - for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) { - n++; - } - - return Smi::FromInt(n); -} + // Calculate the size of the result. + int details_size = kScopeDetailsSize; + Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); -RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) { - HandleScope scope(isolate); - ASSERT(args.length() == 2); - - // Check arguments. - CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); - CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); - - // Find the requested scope. - int n = 0; - ScopeIterator it(isolate, fun); - for (; !it.Done() && n < index; it.Next()) { - n++; - } - if (it.Done()) { - return isolate->heap()->undefined_value(); - } + // Fill in scope details. + details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); + Handle<JSObject> scope_object = it.ScopeObject(); + RETURN_IF_EMPTY_HANDLE(isolate, scope_object); + details->set(kScopeDetailsObjectIndex, *scope_object); - return MaterializeScopeDetails(isolate, &it); + return *isolate->factory()->NewJSArrayWithElements(details); } diff --git a/deps/v8/src/runtime.h b/deps/v8/src/runtime.h index 7305256de7..ef351da962 100644 --- a/deps/v8/src/runtime.h +++ b/deps/v8/src/runtime.h @@ -98,8 +98,6 @@ namespace internal { F(AllocateInNewSpace, 1, 1) \ F(SetNativeFlag, 1, 1) \ F(StoreArrayLiteralElement, 5, 1) \ - F(DebugCallbackSupportsStepping, 1, 1) \ - F(DebugPrepareStepInIfStepping, 1, 1) \ \ /* Array join support */ \ F(PushIfAbsent, 2, 1) \ @@ -325,7 +323,6 @@ namespace internal { F(PushWithContext, 2, 1) \ F(PushCatchContext, 3, 1) \ F(PushBlockContext, 2, 1) \ - F(PushModuleContext, 2, 1) \ F(DeleteContextSlot, 2, 1) \ F(LoadContextSlot, 2, 2) \ F(LoadContextSlotNoReferenceError, 2, 2) \ @@ -403,8 +400,6 @@ namespace internal { F(GetFrameDetails, 2, 1) \ F(GetScopeCount, 2, 1) \ F(GetScopeDetails, 4, 1) \ - F(GetFunctionScopeCount, 1, 1) \ - F(GetFunctionScopeDetails, 2, 1) \ F(DebugPrintScopes, 0, 1) \ F(GetThreadCount, 1, 1) \ F(GetThreadDetails, 2, 1) \ diff --git a/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc index f24af2ed26..7901b5d826 100755 --- a/deps/v8/src/scanner.cc +++ b/deps/v8/src/scanner.cc @@ -611,7 +611,7 @@ void Scanner::SeekForward(int pos) { } -bool Scanner::ScanEscape() { +void Scanner::ScanEscape() { uc32 c = c0_; Advance(); @@ -621,7 +621,7 @@ bool Scanner::ScanEscape() { if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance(); // Allow LF+CR newlines in multiline string literals. if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance(); - return true; + return; } switch (c) { @@ -635,13 +635,13 @@ bool Scanner::ScanEscape() { case 't' : c = '\t'; break; case 'u' : { c = ScanHexNumber(4); - if (c < 0) return false; + if (c < 0) c = 'u'; break; } case 'v' : c = '\v'; break; case 'x' : { c = ScanHexNumber(2); - if (c < 0) return false; + if (c < 0) c = 'x'; break; } case '0' : // fall through @@ -654,11 +654,10 @@ bool Scanner::ScanEscape() { case '7' : c = ScanOctalEscape(c, 2); break; } - // According to ECMA-262, section 7.8.4, characters not covered by the - // above cases should be illegal, but they are commonly handled as - // non-escaped characters by JS VMs. + // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these + // should be illegal, but they are commonly handled + // as non-escaped characters by JS VMs. AddLiteralChar(c); - return true; } @@ -697,7 +696,8 @@ Token::Value Scanner::ScanString() { uc32 c = c0_; Advance(); if (c == '\\') { - if (c0_ < 0 || !ScanEscape()) return Token::ILLEGAL; + if (c0_ < 0) return Token::ILLEGAL; + ScanEscape(); } else { AddLiteralChar(c); } diff --git a/deps/v8/src/scanner.h b/deps/v8/src/scanner.h index 4de413b885..045e7d27a6 100644 --- a/deps/v8/src/scanner.h +++ b/deps/v8/src/scanner.h @@ -520,16 +520,13 @@ class Scanner { Token::Value ScanIdentifierOrKeyword(); Token::Value ScanIdentifierSuffix(LiteralScope* literal); + void ScanEscape(); Token::Value ScanString(); - // Scans an escape-sequence which is part of a string and adds the - // decoded character to the current literal. Returns true if a pattern - // is scanned. - bool ScanEscape(); - // Decodes a Unicode escape-sequence which is part of an identifier. + // Decodes a unicode escape-sequence which is part of an identifier. // If the escape sequence cannot be decoded the result is kBadChar. uc32 ScanIdentifierUnicodeEscape(); - // Scans a Unicode escape-sequence and adds its characters, + // Recognizes a uniocde escape-sequence and adds its characters, // uninterpreted, to the current literal. Used for parsing RegExp // flags. bool ScanLiteralUnicodeEscape(); diff --git a/deps/v8/src/scopeinfo.cc b/deps/v8/src/scopeinfo.cc index f50af304a2..0f36234701 100644 --- a/deps/v8/src/scopeinfo.cc +++ b/deps/v8/src/scopeinfo.cc @@ -53,7 +53,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) { FunctionVariableInfo function_name_info; VariableMode function_variable_mode; if (scope->is_function_scope() && scope->function() != NULL) { - Variable* var = scope->function()->proxy()->var(); + Variable* var = scope->function()->var(); if (!var->is_used()) { function_name_info = UNUSED; } else if (var->IsContextSlot()) { @@ -129,8 +129,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) { // If present, add the function variable name and its index. ASSERT(index == scope_info->FunctionNameEntryIndex()); if (has_function_name) { - int var_index = scope->function()->proxy()->var()->index(); - scope_info->set(index++, *scope->function()->proxy()->name()); + int var_index = scope->function()->var()->index(); + scope_info->set(index++, *scope->function()->name()); scope_info->set(index++, Smi::FromInt(var_index)); ASSERT(function_name_info != STACK || (var_index == scope_info->StackLocalCount() && @@ -142,9 +142,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) { ASSERT(index == scope_info->length()); ASSERT(scope->num_parameters() == scope_info->ParameterCount()); ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount()); - ASSERT(scope->num_heap_slots() == scope_info->ContextLength() || - (scope->num_heap_slots() == kVariablePartIndex && - scope_info->ContextLength() == 0)); + ASSERT(scope->num_heap_slots() == scope_info->ContextLength()); return scope_info; } diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc index 2c61a7523a..c142c3d61a 100644 --- a/deps/v8/src/scopes.cc +++ b/deps/v8/src/scopes.cc @@ -388,17 +388,14 @@ Variable* Scope::LocalLookup(Handle<String> name) { // Check context slot lookup. VariableMode mode; - Variable::Location location = Variable::CONTEXT; InitializationFlag init_flag; int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag); if (index < 0) { // Check parameters. + mode = VAR; + init_flag = kCreatedInitialized; index = scope_info_->ParameterIndex(*name); if (index < 0) return NULL; - - mode = DYNAMIC; - location = Variable::LOOKUP; - init_flag = kCreatedInitialized; } Variable* var = @@ -408,27 +405,21 @@ Variable* Scope::LocalLookup(Handle<String> name) { true, Variable::NORMAL, init_flag); - var->AllocateTo(location, index); + var->AllocateTo(Variable::CONTEXT, index); return var; } Variable* Scope::LookupFunctionVar(Handle<String> name, AstNodeFactory<AstNullVisitor>* factory) { - if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) { - return function_->proxy()->var(); + if (function_ != NULL && function_->name().is_identical_to(name)) { + return function_->var(); } else if (!scope_info_.is_null()) { // If we are backed by a scope info, try to lookup the variable there. VariableMode mode; int index = scope_info_->FunctionContextSlotIndex(*name, &mode); if (index < 0) return NULL; - Variable* var = new Variable( - this, name, mode, true /* is valid LHS */, - Variable::NORMAL, kCreatedInitialized); - VariableProxy* proxy = factory->NewVariableProxy(var); - VariableDeclaration* declaration = - factory->NewVariableDeclaration(proxy, mode, this); - DeclareFunctionVar(declaration); + Variable* var = DeclareFunctionVar(name, mode, factory); var->AllocateTo(Variable::CONTEXT, index); return var; } else { @@ -820,7 +811,7 @@ void Scope::Print(int n) { // Function name, if any (named function literals, only). if (function_ != NULL) { Indent(n1, "// (local) function name: "); - PrintName(function_->proxy()->name()); + PrintName(function_->name()); PrintF("\n"); } @@ -853,7 +844,7 @@ void Scope::Print(int n) { // Print locals. Indent(n1, "// function var\n"); if (function_ != NULL) { - PrintVar(n1, function_->proxy()->var()); + PrintVar(n1, function_->var()); } Indent(n1, "// temporary vars\n"); @@ -978,14 +969,10 @@ bool Scope::ResolveVariable(CompilationInfo* info, break; case BOUND_EVAL_SHADOWED: - // We either found a variable binding that might be shadowed by eval or - // gave up on it (e.g. by encountering a local with the same in the outer - // scope which was not promoted to a context, this can happen if we use - // debugger to evaluate arbitrary expressions at a break point). + // We found a variable variable binding that might be shadowed + // by 'eval' introduced variable bindings. if (var->is_global()) { var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); - } else if (var->is_dynamic()) { - var = NonLocal(proxy->name(), DYNAMIC); } else { Variable* invalidated = var; var = NonLocal(proxy->name(), DYNAMIC_LOCAL); @@ -1119,7 +1106,7 @@ bool Scope::MustAllocateInContext(Variable* var) { // Exceptions: temporary variables are never allocated in a context; // catch-bound variables are always allocated in a context. if (var->mode() == TEMPORARY) return false; - if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; + if (is_catch_scope() || is_block_scope()) return true; return var->has_forced_context_allocation() || scope_calls_eval_ || inner_scope_calls_eval_ || @@ -1237,7 +1224,7 @@ void Scope::AllocateNonParameterLocals() { // because of the current ScopeInfo implementation (see // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). if (function_ != NULL) { - AllocateNonParameterLocal(function_->proxy()->var()); + AllocateNonParameterLocal(function_->var()); } } @@ -1263,8 +1250,7 @@ void Scope::AllocateVariablesRecursively() { // Force allocation of a context for this scope if necessary. For a 'with' // scope and for a function scope that makes an 'eval' call we need a context, // even if no local variables were statically allocated in the scope. - // Likewise for modules. - bool must_have_context = is_with_scope() || is_module_scope() || + bool must_have_context = is_with_scope() || (is_function_scope() && calls_eval()); // If we didn't allocate any locals in the local context, then we only @@ -1280,14 +1266,14 @@ void Scope::AllocateVariablesRecursively() { int Scope::StackLocalCount() const { return num_stack_slots() - - (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); + (function_ != NULL && function_->var()->IsStackLocal() ? 1 : 0); } int Scope::ContextLocalCount() const { if (num_heap_slots() == 0) return 0; return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - - (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); + (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); } } } // namespace v8::internal diff --git a/deps/v8/src/scopes.h b/deps/v8/src/scopes.h index be6705b324..174dbdbf04 100644 --- a/deps/v8/src/scopes.h +++ b/deps/v8/src/scopes.h @@ -126,9 +126,15 @@ class Scope: public ZoneObject { // Declare the function variable for a function literal. This variable // is in an intermediate scope between this function scope and the the // outer scope. Only possible for function scopes; at most one variable. - void DeclareFunctionVar(VariableDeclaration* declaration) { - ASSERT(is_function_scope()); - function_ = declaration; + template<class Visitor> + Variable* DeclareFunctionVar(Handle<String> name, + VariableMode mode, + AstNodeFactory<Visitor>* factory) { + ASSERT(is_function_scope() && function_ == NULL); + Variable* function_var = new Variable( + this, name, mode, true, Variable::NORMAL, kCreatedInitialized); + function_ = factory->NewVariableProxy(function_var); + return function_var; } // Declare a parameter in this scope. When there are duplicated @@ -306,8 +312,9 @@ class Scope: public ZoneObject { Variable* receiver() { return receiver_; } // The variable holding the function literal for named function - // literals, or NULL. Only valid for function scopes. - VariableDeclaration* function() const { + // literals, or NULL. + // Only valid for function scopes. + VariableProxy* function() const { ASSERT(is_function_scope()); return function_; } @@ -442,7 +449,7 @@ class Scope: public ZoneObject { // Convenience variable. Variable* receiver_; // Function variable, if any; function scopes only. - VariableDeclaration* function_; + VariableProxy* function_; // Convenience variable; function scopes only. Variable* arguments_; // Interface; module scopes only. diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc index cf8e5e18e6..01d5f1c7bc 100644 --- a/deps/v8/src/serialize.cc +++ b/deps/v8/src/serialize.cc @@ -244,7 +244,7 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { "Isolate::" #hacker_name "_address", FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) NULL -#undef BUILD_NAME_LITERAL +#undef C }; for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) { diff --git a/deps/v8/src/small-pointer-list.h b/deps/v8/src/small-pointer-list.h index 75fea061ad..6c5ce890d2 100644 --- a/deps/v8/src/small-pointer-list.h +++ b/deps/v8/src/small-pointer-list.h @@ -69,12 +69,6 @@ class SmallPointerList { data_ = kEmptyTag; } - void Sort() { - if ((data_ & kTagMask) == kListTag) { - list()->Sort(compare_value); - } - } - bool is_empty() const { return length() == 0; } int length() const { @@ -165,10 +159,6 @@ class SmallPointerList { private: typedef ZoneList<T*> PointerList; - static int compare_value(T* const* a, T* const* b) { - return Compare<T>(**a, **b); - } - static const intptr_t kEmptyTag = 1; static const intptr_t kSingletonTag = 0; static const intptr_t kListTag = 2; diff --git a/deps/v8/src/spaces-inl.h b/deps/v8/src/spaces-inl.h index ed78fc7a15..3709009c9b 100644 --- a/deps/v8/src/spaces-inl.h +++ b/deps/v8/src/spaces-inl.h @@ -164,7 +164,7 @@ Page* Page::Initialize(Heap* heap, Executability executable, PagedSpace* owner) { Page* page = reinterpret_cast<Page*>(chunk); - ASSERT(chunk->size() <= static_cast<size_t>(kPageSize)); + ASSERT(chunk->size() == static_cast<size_t>(kPageSize)); ASSERT(chunk->owner() == owner); owner->IncreaseCapacity(page->area_size()); owner->Free(page->area_start(), page->area_size()); @@ -295,27 +295,11 @@ MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) { MaybeObject* NewSpace::AllocateRaw(int size_in_bytes) { Address old_top = allocation_info_.top; -#ifdef DEBUG - // If we are stressing compaction we waste some memory in new space - // in order to get more frequent GCs. - if (FLAG_stress_compaction && !HEAP->linear_allocation()) { - if (allocation_info_.limit - old_top >= size_in_bytes * 4) { - int filler_size = size_in_bytes * 4; - for (int i = 0; i < filler_size; i += kPointerSize) { - *(reinterpret_cast<Object**>(old_top + i)) = - HEAP->one_pointer_filler_map(); - } - old_top += filler_size; - allocation_info_.top += filler_size; - } - } -#endif - if (allocation_info_.limit - old_top < size_in_bytes) { return SlowAllocateRaw(size_in_bytes); } - Object* obj = HeapObject::FromAddress(old_top); + Object* obj = HeapObject::FromAddress(allocation_info_.top); allocation_info_.top += size_in_bytes; ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc index a5d61ebb59..929a45fb21 100644 --- a/deps/v8/src/spaces.cc +++ b/deps/v8/src/spaces.cc @@ -572,10 +572,11 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, } -Page* MemoryAllocator::AllocatePage(intptr_t size, - PagedSpace* owner, +Page* MemoryAllocator::AllocatePage(PagedSpace* owner, Executability executable) { - MemoryChunk* chunk = AllocateChunk(size, executable, owner); + MemoryChunk* chunk = AllocateChunk(owner->AreaSize(), + executable, + owner); if (chunk == NULL) return NULL; @@ -584,8 +585,8 @@ Page* MemoryAllocator::AllocatePage(intptr_t size, LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size, - Space* owner, - Executability executable) { + Executability executable, + Space* owner) { MemoryChunk* chunk = AllocateChunk(object_size, executable, owner); if (chunk == NULL) return NULL; return LargePage::Initialize(isolate_->heap(), chunk); @@ -839,6 +840,7 @@ MaybeObject* PagedSpace::FindObject(Address addr) { bool PagedSpace::CanExpand() { ASSERT(max_capacity_ % AreaSize() == 0); + ASSERT(Capacity() % AreaSize() == 0); if (Capacity() == max_capacity_) return false; @@ -853,14 +855,8 @@ bool PagedSpace::CanExpand() { bool PagedSpace::Expand() { if (!CanExpand()) return false; - intptr_t size = AreaSize(); - - if (anchor_.next_page() == &anchor_) { - size = SizeOfFirstPage(); - } - - Page* p = heap()->isolate()->memory_allocator()->AllocatePage( - size, this, executable()); + Page* p = heap()->isolate()->memory_allocator()-> + AllocatePage(this, executable()); if (p == NULL) return false; ASSERT(Capacity() <= max_capacity_); @@ -871,38 +867,6 @@ bool PagedSpace::Expand() { } -intptr_t PagedSpace::SizeOfFirstPage() { - int size = 0; - switch (identity()) { - case OLD_POINTER_SPACE: - size = 64 * kPointerSize * KB; - break; - case OLD_DATA_SPACE: - size = 192 * KB; - break; - case MAP_SPACE: - size = 128 * KB; - break; - case CELL_SPACE: - size = 96 * KB; - break; - case CODE_SPACE: - if (kPointerSize == 8) { - // On x64 we allocate code pages in a special way (from the reserved - // 2Byte area). That part of the code is not yet upgraded to handle - // small pages. - size = AreaSize(); - } else { - size = 384 * KB; - } - break; - default: - UNREACHABLE(); - } - return Min(size, AreaSize()); -} - - int PagedSpace::CountTotalPages() { PageIterator it(this); int count = 0; @@ -946,6 +910,7 @@ void PagedSpace::ReleasePage(Page* page) { } ASSERT(Capacity() > 0); + ASSERT(Capacity() % AreaSize() == 0); accounting_stats_.ShrinkSpace(AreaSize()); } @@ -1084,7 +1049,6 @@ bool NewSpace::SetUp(int reserved_semispace_capacity, if (!to_space_.Commit()) { return false; } - ASSERT(!from_space_.is_committed()); // No need to use memory yet. start_ = chunk_base_; address_mask_ = ~(2 * reserved_semispace_capacity - 1); @@ -2626,7 +2590,7 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size, } LargePage* page = heap()->isolate()->memory_allocator()-> - AllocateLargePage(object_size, this, executable); + AllocateLargePage(object_size, executable, this); if (page == NULL) return Failure::RetryAfterGC(identity()); ASSERT(page->area_size() >= object_size); diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h index b0ecc5d004..9e74a88a33 100644 --- a/deps/v8/src/spaces.h +++ b/deps/v8/src/spaces.h @@ -637,10 +637,8 @@ class MemoryChunk { friend class MemoryAllocator; }; - STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); - // ----------------------------------------------------------------------------- // A page is a memory chunk of a size 1MB. Large object pages may be larger. // @@ -952,11 +950,11 @@ class MemoryAllocator { void TearDown(); - Page* AllocatePage( - intptr_t size, PagedSpace* owner, Executability executable); + Page* AllocatePage(PagedSpace* owner, Executability executable); - LargePage* AllocateLargePage( - intptr_t object_size, Space* owner, Executability executable); + LargePage* AllocateLargePage(intptr_t object_size, + Executability executable, + Space* owner); void Free(MemoryChunk* chunk); @@ -1522,10 +1520,6 @@ class PagedSpace : public Space { return size_in_bytes - wasted; } - void ResetFreeList() { - free_list_.Reset(); - } - // Set space allocation info. void SetTop(Address top, Address limit) { ASSERT(top == limit || @@ -1633,8 +1627,6 @@ class PagedSpace : public Space { // Maximum capacity of this space. intptr_t max_capacity_; - intptr_t SizeOfFirstPage(); - // Accounting information for this space. AllocationStats accounting_stats_; @@ -2377,6 +2369,11 @@ class FixedSpace : public PagedSpace { // Prepares for a mark-compact GC. virtual void PrepareForMarkCompact(); + protected: + void ResetFreeList() { + free_list_.Reset(); + } + private: // The size of objects in this space. int object_size_in_bytes_; diff --git a/deps/v8/src/string.js b/deps/v8/src/string.js index 6115930b6c..84dde3dc27 100644 --- a/deps/v8/src/string.js +++ b/deps/v8/src/string.js @@ -189,9 +189,7 @@ function StringMatch(regexp) { if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0); %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]); // lastMatchInfo is defined in regexp.js. - var result = %StringMatch(subject, regexp, lastMatchInfo); - if (result !== null) lastMatchInfoOverride = null; - return result; + return %StringMatch(subject, regexp, lastMatchInfo); } // Non-regexp argument. regexp = new $RegExp(regexp); @@ -237,28 +235,10 @@ function StringReplace(search, replace) { replace); } } else { - if (lastMatchInfoOverride == null) { - return %StringReplaceRegExpWithString(subject, - search, - TO_STRING_INLINE(replace), - lastMatchInfo); - } else { - // We use this hack to detect whether StringReplaceRegExpWithString - // found at least one hit. In that case we need to remove any - // override. - var saved_subject = lastMatchInfo[LAST_SUBJECT_INDEX]; - lastMatchInfo[LAST_SUBJECT_INDEX] = 0; - var answer = %StringReplaceRegExpWithString(subject, - search, - TO_STRING_INLINE(replace), - lastMatchInfo); - if (%_IsSmi(lastMatchInfo[LAST_SUBJECT_INDEX])) { - lastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject; - } else { - lastMatchInfoOverride = null; - } - return answer; - } + return %StringReplaceRegExpWithString(subject, + search, + TO_STRING_INLINE(replace), + lastMatchInfo); } } @@ -277,34 +257,47 @@ function StringReplace(search, replace) { if (start < 0) return subject; var end = start + search.length; - var result = SubString(subject, 0, start); + var builder = new ReplaceResultBuilder(subject); + // prefix + builder.addSpecialSlice(0, start); // Compute the string to replace with. if (IS_SPEC_FUNCTION(replace)) { var receiver = %GetDefaultReceiver(replace); - result += %_CallFunction(receiver, search, start, subject, replace); + builder.add(%_CallFunction(receiver, + search, + start, + subject, + replace)); } else { reusableMatchInfo[CAPTURE0] = start; reusableMatchInfo[CAPTURE1] = end; replace = TO_STRING_INLINE(replace); - result = ExpandReplacement(replace, subject, reusableMatchInfo, result); + ExpandReplacement(replace, subject, reusableMatchInfo, builder); } - return result + SubString(subject, end, subject.length); + // suffix + builder.addSpecialSlice(end, subject.length); + + return builder.generate(); } // Expand the $-expressions in the string and return a new string with // the result. -function ExpandReplacement(string, subject, matchInfo, result) { +function ExpandReplacement(string, subject, matchInfo, builder) { var length = string.length; + var builder_elements = builder.elements; var next = %StringIndexOf(string, '$', 0); if (next < 0) { - if (length > 0) result += string; - return result; + if (length > 0) builder_elements.push(string); + return; } - if (next > 0) result += SubString(string, 0, next); + // Compute the number of captures; see ECMA-262, 15.5.4.11, p. 102. + var m = NUMBER_OF_CAPTURES(matchInfo) >> 1; // Includes the match. + + if (next > 0) builder_elements.push(SubString(string, 0, next)); while (true) { var expansion = '$'; @@ -313,21 +306,51 @@ function ExpandReplacement(string, subject, matchInfo, result) { var peek = %_StringCharCodeAt(string, position); if (peek == 36) { // $$ ++position; - result += '$'; + builder_elements.push('$'); } else if (peek == 38) { // $& - match ++position; - result += SubString(subject, matchInfo[CAPTURE0], matchInfo[CAPTURE1]); + builder.addSpecialSlice(matchInfo[CAPTURE0], + matchInfo[CAPTURE1]); } else if (peek == 96) { // $` - prefix ++position; - result += SubString(subject, 0, matchInfo[CAPTURE0]); + builder.addSpecialSlice(0, matchInfo[CAPTURE0]); } else if (peek == 39) { // $' - suffix ++position; - result += SubString(subject, matchInfo[CAPTURE1], subject.length); + builder.addSpecialSlice(matchInfo[CAPTURE1], subject.length); + } else if (peek >= 48 && peek <= 57) { // $n, 0 <= n <= 9 + ++position; + var n = peek - 48; + if (position < length) { + peek = %_StringCharCodeAt(string, position); + // $nn, 01 <= nn <= 99 + if (n != 0 && peek == 48 || peek >= 49 && peek <= 57) { + var nn = n * 10 + (peek - 48); + if (nn < m) { + // If the two digit capture reference is within range of + // the captures, we use it instead of the single digit + // one. Otherwise, we fall back to using the single + // digit reference. This matches the behavior of + // SpiderMonkey. + ++position; + n = nn; + } + } + } + if (0 < n && n < m) { + addCaptureString(builder, matchInfo, n); + } else { + // Because of the captures range check in the parsing of two + // digit capture references, we can only enter here when a + // single digit capture reference is outside the range of + // captures. + builder_elements.push('$'); + --position; + } } else { - result += '$'; + builder_elements.push('$'); } } else { - result += '$'; + builder_elements.push('$'); } // Go the the next $ in the string. @@ -337,17 +360,16 @@ function ExpandReplacement(string, subject, matchInfo, result) { // haven't reached the end, we need to append the suffix. if (next < 0) { if (position < length) { - result += SubString(string, position, length); + builder_elements.push(SubString(string, position, length)); } - return result; + return; } // Append substring between the previous and the next $ character. if (next > position) { - result += SubString(string, position, next); + builder_elements.push(SubString(string, position, next)); } } - return result; } @@ -364,6 +386,18 @@ function CaptureString(string, lastCaptureInfo, index) { } +// Add the string of a given regular expression capture to the +// ReplaceResultBuilder +function addCaptureString(builder, matchInfo, index) { + // Scale the index. + var scaled = index << 1; + // Compute start and end. + var start = matchInfo[CAPTURE(scaled)]; + if (start < 0) return; + var end = matchInfo[CAPTURE(scaled + 1)]; + builder.addSpecialSlice(start, end); +} + // TODO(lrn): This array will survive indefinitely if replace is never // called again. However, it will be empty, since the contents are cleared // in the finally block. @@ -393,22 +427,14 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { return subject; } var len = res.length; + var i = 0; if (NUMBER_OF_CAPTURES(lastMatchInfo) == 2) { - // If the number of captures is two then there are no explicit captures in - // the regexp, just the implicit capture that captures the whole match. In - // this case we can simplify quite a bit and end up with something faster. - // The builder will consist of some integers that indicate slices of the - // input string and some replacements that were returned from the replace - // function. var match_start = 0; var override = new InternalArray(null, 0, subject); var receiver = %GetDefaultReceiver(replace); - for (var i = 0; i < len; i++) { + while (i < len) { var elem = res[i]; if (%_IsSmi(elem)) { - // Integers represent slices of the original string. Use these to - // get the offsets we need for the override array (so things like - // RegExp.leftContext work during the callback function. if (elem > 0) { match_start = (elem >> 11) + (elem & 0x7ff); } else { @@ -420,25 +446,23 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { lastMatchInfoOverride = override; var func_result = %_CallFunction(receiver, elem, match_start, subject, replace); - // Overwrite the i'th element in the results with the string we got - // back from the callback function. res[i] = TO_STRING_INLINE(func_result); match_start += elem.length; } + i++; } } else { var receiver = %GetDefaultReceiver(replace); - for (var i = 0; i < len; i++) { + while (i < len) { var elem = res[i]; if (!%_IsSmi(elem)) { // elem must be an Array. // Use the apply argument as backing for global RegExp properties. lastMatchInfoOverride = elem; var func_result = %Apply(replace, receiver, elem, 0, elem.length); - // Overwrite the i'th element in the results with the string we got - // back from the callback function. res[i] = TO_STRING_INLINE(func_result); } + i++; } } var resultBuilder = new ReplaceResultBuilder(subject, res); @@ -452,8 +476,9 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) { function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { var matchInfo = DoRegExpExec(regexp, subject, 0); if (IS_NULL(matchInfo)) return subject; + var result = new ReplaceResultBuilder(subject); var index = matchInfo[CAPTURE0]; - var result = SubString(subject, 0, index); + result.addSpecialSlice(0, index); var endOfMatch = matchInfo[CAPTURE1]; // Compute the parameter list consisting of the match, captures, index, // and subject for the replace function invocation. @@ -465,7 +490,8 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { // No captures, only the match, which is always valid. var s = SubString(subject, index, endOfMatch); // Don't call directly to avoid exposing the built-in global object. - replacement = %_CallFunction(receiver, s, index, subject, replace); + replacement = + %_CallFunction(receiver, s, index, subject, replace); } else { var parameters = new InternalArray(m + 2); for (var j = 0; j < m; j++) { @@ -477,10 +503,11 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) { replacement = %Apply(replace, receiver, parameters, 0, j + 2); } - result += replacement; // The add method converts to string if necessary. + result.add(replacement); // The add method converts to string if necessary. // Can't use matchInfo any more from here, since the function could // overwrite it. - return result + SubString(subject, endOfMatch, subject.length); + result.addSpecialSlice(endOfMatch, subject.length); + return result.generate(); } diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc index bd7163a2f1..3371b1bf4a 100644 --- a/deps/v8/src/stub-cache.cc +++ b/deps/v8/src/stub-cache.cc @@ -939,8 +939,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { ASSERT(args[0]->IsJSObject()); ASSERT(args[1]->IsJSObject()); - ASSERT(args[3]->IsSmi()); - AccessorInfo* callback = AccessorInfo::cast(args[4]); + AccessorInfo* callback = AccessorInfo::cast(args[3]); Address getter_address = v8::ToCData<Address>(callback->getter()); v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); ASSERT(fun != NULL); @@ -951,7 +950,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { // Leaving JavaScript. VMState state(isolate, EXTERNAL); ExternalCallbackScope call_scope(isolate, getter_address); - result = fun(v8::Utils::ToLocal(args.at<String>(5)), info); + result = fun(v8::Utils::ToLocal(args.at<String>(4)), info); } RETURN_IF_SCHEDULED_EXCEPTION(isolate); if (result.IsEmpty()) return HEAP->undefined_value(); @@ -998,8 +997,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) { ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); ASSERT(args[2]->IsJSObject()); // Receiver. ASSERT(args[3]->IsJSObject()); // Holder. - ASSERT(args[5]->IsSmi()); // Isolate. - ASSERT(args.length() == 6); + ASSERT(args.length() == 5); // Last arg is data object. Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); v8::NamedPropertyGetter getter = @@ -1052,7 +1050,7 @@ static MaybeObject* LoadWithInterceptor(Arguments* args, ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); Handle<JSObject> receiver_handle = args->at<JSObject>(2); Handle<JSObject> holder_handle = args->at<JSObject>(3); - ASSERT(args->length() == 6); + ASSERT(args->length() == 5); // Last arg is data object. Isolate* isolate = receiver_handle->GetIsolate(); diff --git a/deps/v8/src/utils.cc b/deps/v8/src/utils.cc index 7e8c088dd4..89ef4c6e3e 100644 --- a/deps/v8/src/utils.cc +++ b/deps/v8/src/utils.cc @@ -89,19 +89,4 @@ char* SimpleStringBuilder::Finalize() { return buffer_.start(); } - -const DivMagicNumbers DivMagicNumberFor(int32_t divisor) { - switch (divisor) { - case 3: return DivMagicNumberFor3; - case 5: return DivMagicNumberFor5; - case 7: return DivMagicNumberFor7; - case 9: return DivMagicNumberFor9; - case 11: return DivMagicNumberFor11; - case 25: return DivMagicNumberFor25; - case 125: return DivMagicNumberFor125; - case 625: return DivMagicNumberFor625; - default: return InvalidDivMagicNumber; - } -} - } } // namespace v8::internal diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h index f116c14db3..1d40c98b9e 100644 --- a/deps/v8/src/utils.h +++ b/deps/v8/src/utils.h @@ -85,32 +85,6 @@ inline int WhichPowerOf2(uint32_t x) { } -// Magic numbers for integer division. -// These are kind of 2's complement reciprocal of the divisors. -// Details and proofs can be found in: -// - Hacker's Delight, Henry S. Warren, Jr. -// - The PowerPC Compiler Writer’s Guide -// and probably many others. -// See details in the implementation of the algorithm in -// lithium-codegen-arm.cc : LCodeGen::TryEmitSignedIntegerDivisionByConstant(). -struct DivMagicNumbers { - unsigned M; - unsigned s; -}; - -const DivMagicNumbers InvalidDivMagicNumber= {0, 0}; -const DivMagicNumbers DivMagicNumberFor3 = {0x55555556, 0}; -const DivMagicNumbers DivMagicNumberFor5 = {0x66666667, 1}; -const DivMagicNumbers DivMagicNumberFor7 = {0x92492493, 2}; -const DivMagicNumbers DivMagicNumberFor9 = {0x38e38e39, 1}; -const DivMagicNumbers DivMagicNumberFor11 = {0x2e8ba2e9, 1}; -const DivMagicNumbers DivMagicNumberFor25 = {0x51eb851f, 3}; -const DivMagicNumbers DivMagicNumberFor125 = {0x10624dd3, 3}; -const DivMagicNumbers DivMagicNumberFor625 = {0x68db8bad, 8}; - -const DivMagicNumbers DivMagicNumberFor(int32_t divisor); - - // The C++ standard leaves the semantics of '>>' undefined for // negative signed operands. Most implementations do the right thing, // though. diff --git a/deps/v8/src/v8-counters.h b/deps/v8/src/v8-counters.h index 94a5264380..6db9c77edc 100644 --- a/deps/v8/src/v8-counters.h +++ b/deps/v8/src/v8-counters.h @@ -236,8 +236,6 @@ namespace internal { SC(math_sin, V8.MathSin) \ SC(math_sqrt, V8.MathSqrt) \ SC(math_tan, V8.MathTan) \ - SC(array_bounds_checks_seen, V8.ArrayBoundsChecksSeen) \ - SC(array_bounds_checks_removed, V8.ArrayBoundsChecksRemoved) \ SC(transcendental_cache_hit, V8.TranscendentalCacheHit) \ SC(transcendental_cache_miss, V8.TranscendentalCacheMiss) \ SC(stack_interrupts, V8.StackInterrupts) \ diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc index 2910a0700d..1157c9d388 100644 --- a/deps/v8/src/v8.cc +++ b/deps/v8/src/v8.cc @@ -27,13 +27,11 @@ #include "v8.h" -#include "assembler.h" #include "isolate.h" #include "elements.h" #include "bootstrapper.h" #include "debug.h" #include "deoptimizer.h" -#include "frames.h" #include "heap-profiler.h" #include "hydrogen.h" #include "lithium-allocator.h" @@ -105,21 +103,13 @@ void V8::TearDown() { ASSERT(isolate->IsDefaultIsolate()); if (!has_been_set_up_ || has_been_disposed_) return; - - ElementsAccessor::TearDown(); - LOperand::TearDownCaches(); - RegisteredExtension::UnregisterAll(); - isolate->TearDown(); - delete isolate; is_running_ = false; has_been_disposed_ = true; delete call_completed_callbacks_; call_completed_callbacks_ = NULL; - - OS::TearDown(); } @@ -250,6 +240,7 @@ Object* V8::FillHeapNumberWithRandom(Object* heap_number, } void V8::InitializeOncePerProcessImpl() { + // Set up the platform OS support. OS::SetUp(); use_crankshaft_ = FLAG_crankshaft; @@ -265,7 +256,7 @@ void V8::InitializeOncePerProcessImpl() { OS::PostSetUp(); - RuntimeProfiler::GlobalSetUp(); + RuntimeProfiler::GlobalSetup(); ElementsAccessor::InitializeOncePerProcess(); @@ -276,9 +267,6 @@ void V8::InitializeOncePerProcessImpl() { } LOperand::SetUpCaches(); - SetUpJSCallerSavedCodeData(); - SamplerRegistry::SetUp(); - ExternalReference::SetUp(); } void V8::InitializeOncePerProcess() { diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h index 6a1766a1a5..bfc5e23390 100644 --- a/deps/v8/src/v8globals.h +++ b/deps/v8/src/v8globals.h @@ -48,10 +48,6 @@ const intptr_t kObjectAlignmentMask = kObjectAlignment - 1; const intptr_t kPointerAlignment = (1 << kPointerSizeLog2); const intptr_t kPointerAlignmentMask = kPointerAlignment - 1; -// Desired alignment for double values. -const intptr_t kDoubleAlignment = 8; -const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1; - // Desired alignment for maps. #if V8_HOST_ARCH_64_BIT const intptr_t kMapAlignmentBits = kObjectAlignmentBits; diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc index 8215639e5b..48ed355e66 100644 --- a/deps/v8/src/version.cc +++ b/deps/v8/src/version.cc @@ -33,9 +33,9 @@ // NOTE these macros are used by the SCons build script so their names // cannot be changed without changing the SCons build script. #define MAJOR_VERSION 3 -#define MINOR_VERSION 10 -#define BUILD_NUMBER 8 -#define PATCH_LEVEL 13 +#define MINOR_VERSION 9 +#define BUILD_NUMBER 24 +#define PATCH_LEVEL 31 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) #define IS_CANDIDATE_VERSION 0 diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc index d179d2a5d5..2845039771 100644 --- a/deps/v8/src/x64/code-stubs-x64.cc +++ b/deps/v8/src/x64/code-stubs-x64.cc @@ -3628,9 +3628,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) { - // rbx : cache cell for call target // rdi : the function to call - Isolate* isolate = masm->isolate(); + // rbx : cache cell for call target Label slow, non_function; // The receiver might implicitly be the global object. This is @@ -3645,9 +3644,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); __ j(not_equal, &call, Label::kNear); // Patch the receiver on the stack with the global receiver object. - __ movq(rcx, GlobalObjectOperand()); - __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); - __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx); + __ movq(rbx, GlobalObjectOperand()); + __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); + __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx); __ bind(&call); } @@ -3657,10 +3656,6 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); __ j(not_equal, &slow); - if (RecordCallTarget()) { - GenerateRecordCallTarget(masm); - } - // Fast-case: Just invoke the function. ParameterCount actual(argc_); @@ -3683,13 +3678,6 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); - if (RecordCallTarget()) { - // If there is a call target cache, mark it megamorphic in the - // non-function case. MegamorphicSentinel is an immortal immovable - // object (undefined) so no write barrier is needed. - __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), - TypeFeedbackCells::MegamorphicSentinel(isolate)); - } // Check for function proxy. __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); __ j(not_equal, &non_function); @@ -5124,24 +5112,56 @@ void SubStringStub::Generate(MacroAssembler* masm) { // rax: string // rbx: instance type // Calculate length of sub string using the smi values. + Label result_longer_than_two; __ movq(rcx, Operand(rsp, kToOffset)); __ movq(rdx, Operand(rsp, kFromOffset)); __ JumpUnlessBothNonNegativeSmi(rcx, rdx, &runtime); __ SmiSub(rcx, rcx, rdx); // Overflow doesn't happen. - __ cmpq(rcx, FieldOperand(rax, String::kLengthOffset)); + __ cmpq(FieldOperand(rax, String::kLengthOffset), rcx); Label not_original_string; - // Shorter than original string's length: an actual substring. - __ j(below, ¬_original_string, Label::kNear); - // Longer than original string's length or negative: unsafe arguments. - __ j(above, &runtime); - // Return original string. + __ j(not_equal, ¬_original_string, Label::kNear); Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->sub_string_native(), 1); __ ret(kArgumentsSize); __ bind(¬_original_string); + // Special handling of sub-strings of length 1 and 2. One character strings + // are handled in the runtime system (looked up in the single character + // cache). Two character strings are looked for in the symbol cache. __ SmiToInteger32(rcx, rcx); + __ cmpl(rcx, Immediate(2)); + __ j(greater, &result_longer_than_two); + __ j(less, &runtime); + + // Sub string of length 2 requested. + // rax: string + // rbx: instance type + // rcx: sub string length (value is 2) + // rdx: from index (smi) + __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &runtime); + + // Get the two characters forming the sub string. + __ SmiToInteger32(rdx, rdx); // From index is no longer smi. + __ movzxbq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize)); + __ movzxbq(rdi, + FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize + 1)); + + // Try to lookup two character string in symbol table. + Label make_two_character_string; + StringHelper::GenerateTwoCharacterSymbolTableProbe( + masm, rbx, rdi, r9, r11, r14, r15, &make_two_character_string); + __ IncrementCounter(counters->sub_string_native(), 1); + __ ret(3 * kPointerSize); + + __ bind(&make_two_character_string); + // Set up registers for allocating the two character string. + __ movzxwq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize)); + __ AllocateAsciiString(rax, rcx, r11, r14, r15, &runtime); + __ movw(FieldOperand(rax, SeqAsciiString::kHeaderSize), rbx); + __ IncrementCounter(counters->sub_string_native(), 1); + __ ret(3 * kPointerSize); + __ bind(&result_longer_than_two); // rax: string // rbx: instance type // rcx: sub string length diff --git a/deps/v8/src/x64/deoptimizer-x64.cc b/deps/v8/src/x64/deoptimizer-x64.cc index f3046b9ce3..f55ebfc3e8 100644 --- a/deps/v8/src/x64/deoptimizer-x64.cc +++ b/deps/v8/src/x64/deoptimizer-x64.cc @@ -111,21 +111,13 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { } -static const byte kJnsInstruction = 0x79; -static const byte kJnsOffset = 0x1f; -static const byte kJaeInstruction = 0x73; -static const byte kJaeOffset = 0x07; -static const byte kCallInstruction = 0xe8; -static const byte kNopByteOne = 0x66; -static const byte kNopByteTwo = 0x90; - void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, Address pc_after, Code* check_code, Code* replacement_code) { Address call_target_address = pc_after - kIntSize; - ASSERT_EQ(check_code->entry(), - Assembler::target_address_at(call_target_address)); + ASSERT(check_code->entry() == + Assembler::target_address_at(call_target_address)); // The stack check code matches the pattern: // // cmp rsp, <limit> @@ -143,16 +135,11 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code, // test rax, <loop nesting depth> // ok: // - if (FLAG_count_based_interrupts) { - ASSERT_EQ(kJnsInstruction, *(call_target_address - 3)); - ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); - } else { - ASSERT_EQ(kJaeInstruction, *(call_target_address - 3)); - ASSERT_EQ(kJaeOffset, *(call_target_address - 2)); - } - ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); - *(call_target_address - 3) = kNopByteOne; - *(call_target_address - 2) = kNopByteTwo; + ASSERT(*(call_target_address - 3) == 0x73 && // jae + *(call_target_address - 2) == 0x07 && // offset + *(call_target_address - 1) == 0xe8); // call + *(call_target_address - 3) = 0x66; // 2 byte nop part 1 + *(call_target_address - 2) = 0x90; // 2 byte nop part 2 Assembler::set_target_address_at(call_target_address, replacement_code->entry()); @@ -170,16 +157,11 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code, Assembler::target_address_at(call_target_address)); // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to // restore the conditional branch. - ASSERT_EQ(kNopByteOne, *(call_target_address - 3)); - ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); - ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); - if (FLAG_count_based_interrupts) { - *(call_target_address - 3) = kJnsInstruction; - *(call_target_address - 2) = kJnsOffset; - } else { - *(call_target_address - 3) = kJaeInstruction; - *(call_target_address - 2) = kJaeOffset; - } + ASSERT(*(call_target_address - 3) == 0x66 && // 2 byte nop part 1 + *(call_target_address - 2) == 0x90 && // 2 byte nop part 2 + *(call_target_address - 1) == 0xe8); // call + *(call_target_address - 3) = 0x73; // jae + *(call_target_address - 2) = 0x07; // offset Assembler::set_target_address_at(call_target_address, check_code->entry()); diff --git a/deps/v8/src/x64/disasm-x64.cc b/deps/v8/src/x64/disasm-x64.cc index 7ed81b47e1..adeda0bb08 100644 --- a/deps/v8/src/x64/disasm-x64.cc +++ b/deps/v8/src/x64/disasm-x64.cc @@ -315,8 +315,7 @@ class DisassemblerX64 { rex_(0), operand_size_(0), group_1_prefix_(0), - byte_size_operand_(false), - instruction_table_(instruction_table.Pointer()) { + byte_size_operand_(false) { tmp_buffer_[0] = '\0'; } @@ -345,7 +344,6 @@ class DisassemblerX64 { byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0. // Byte size operand override. bool byte_size_operand_; - const InstructionTable* const instruction_table_; void setRex(byte rex) { ASSERT_EQ(0x40, rex & 0xF0); @@ -1342,7 +1340,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, data++; } - const InstructionDesc& idesc = instruction_table_->Get(current); + const InstructionDesc& idesc = instruction_table.Get().Get(current); byte_size_operand_ = idesc.byte_size_operation; switch (idesc.type) { case ZERO_OPERANDS_INSTR: diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc index 974269e5dc..d0c4f4dd89 100644 --- a/deps/v8/src/x64/full-codegen-x64.cc +++ b/deps/v8/src/x64/full-codegen-x64.cc @@ -34,7 +34,6 @@ #include "compiler.h" #include "debug.h" #include "full-codegen.h" -#include "isolate-inl.h" #include "parser.h" #include "scopes.h" #include "stub-cache.h" @@ -101,6 +100,11 @@ class JumpPatchSite BASE_EMBEDDED { }; +int FullCodeGenerator::self_optimization_header_size() { + return 20; +} + + // Generate code for a JS function. On entry to the function the receiver // and arguments have been pushed on the stack left to right, with the // return address on top of them. The actual argument count matches the @@ -118,11 +122,32 @@ void FullCodeGenerator::Generate() { CompilationInfo* info = info_; handler_table_ = isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); - profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( - Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget))); SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); + // We can optionally optimize based on counters rather than statistical + // sampling. + if (info->ShouldSelfOptimize()) { + if (FLAG_trace_opt_verbose) { + PrintF("[adding self-optimization header to %s]\n", + *info->function()->debug_name()->ToCString()); + } + has_self_optimization_header_ = true; + MaybeObject* maybe_cell = isolate()->heap()->AllocateJSGlobalPropertyCell( + Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt)); + JSGlobalPropertyCell* cell; + if (maybe_cell->To(&cell)) { + __ movq(rax, Handle<JSGlobalPropertyCell>(cell), + RelocInfo::EMBEDDED_OBJECT); + __ SmiAddConstant(FieldOperand(rax, JSGlobalPropertyCell::kValueOffset), + Smi::FromInt(-1)); + Handle<Code> compile_stub( + isolate()->builtins()->builtin(Builtins::kLazyRecompile)); + __ j(zero, compile_stub, RelocInfo::CODE_TARGET); + ASSERT(masm_->pc_offset() == self_optimization_header_size()); + } + } + #ifdef DEBUG if (strlen(FLAG_stop_at) > 0 && info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { @@ -257,11 +282,11 @@ void FullCodeGenerator::Generate() { // For named function expressions, declare the function name as a // constant. if (scope()->is_function_scope() && scope()->function() != NULL) { - VariableDeclaration* function = scope()->function(); - ASSERT(function->proxy()->var()->mode() == CONST || - function->proxy()->var()->mode() == CONST_HARMONY); - ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); - VisitVariableDeclaration(function); + VariableProxy* proxy = scope()->function(); + ASSERT(proxy->var()->mode() == CONST || + proxy->var()->mode() == CONST_HARMONY); + ASSERT(proxy->var()->location() != Variable::UNALLOCATED); + EmitDeclaration(proxy, proxy->var()->mode(), NULL); } VisitDeclarations(scope()->declarations()); } @@ -297,60 +322,14 @@ void FullCodeGenerator::ClearAccumulator() { } -void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { - __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); - __ SmiAddConstant(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), - Smi::FromInt(-delta)); -} - - -void FullCodeGenerator::EmitProfilingCounterReset() { - int reset_value = FLAG_interrupt_budget; - if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { - // Self-optimization is a one-off thing; if it fails, don't try again. - reset_value = Smi::kMaxValue; - } - if (isolate()->IsDebuggerActive()) { - // Detect debug break requests as soon as possible. - reset_value = 10; - } - __ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT); - __ movq(kScratchRegister, - reinterpret_cast<uint64_t>(Smi::FromInt(reset_value)), - RelocInfo::NONE); - __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), - kScratchRegister); -} - - -static const int kMaxBackEdgeWeight = 127; -static const int kBackEdgeDistanceDivisor = 162; - - void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, Label* back_edge_target) { Comment cmnt(masm_, "[ Stack check"); Label ok; - - if (FLAG_count_based_interrupts) { - int weight = 1; - if (FLAG_weighted_back_edges) { - ASSERT(back_edge_target->is_bound()); - int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); - weight = Min(kMaxBackEdgeWeight, - Max(1, distance / kBackEdgeDistanceDivisor)); - } - EmitProfilingCounterDecrement(weight); - __ j(positive, &ok, Label::kNear); - InterruptStub stub; - __ CallStub(&stub); - } else { - __ CompareRoot(rsp, Heap::kStackLimitRootIndex); - __ j(above_equal, &ok, Label::kNear); - StackCheckStub stub; - __ CallStub(&stub); - } - + __ CompareRoot(rsp, Heap::kStackLimitRootIndex); + __ j(above_equal, &ok, Label::kNear); + StackCheckStub stub; + __ CallStub(&stub); // Record a mapping of this PC offset to the OSR id. This is used to find // the AST id from the unoptimized code in order to use it as a key into // the deoptimization input data found in the optimized code. @@ -363,10 +342,6 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, ASSERT(loop_depth() > 0); __ testl(rax, Immediate(Min(loop_depth(), Code::kMaxLoopNestingMarker))); - if (FLAG_count_based_interrupts) { - EmitProfilingCounterReset(); - } - __ bind(&ok); PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR @@ -386,31 +361,6 @@ void FullCodeGenerator::EmitReturnSequence() { __ push(rax); __ CallRuntime(Runtime::kTraceExit, 1); } - if (FLAG_interrupt_at_exit || FLAG_self_optimization) { - // Pretend that the exit is a backwards jump to the entry. - int weight = 1; - if (info_->ShouldSelfOptimize()) { - weight = FLAG_interrupt_budget / FLAG_self_opt_count; - } else if (FLAG_weighted_back_edges) { - int distance = masm_->pc_offset(); - weight = Min(kMaxBackEdgeWeight, - Max(1, distance = kBackEdgeDistanceDivisor)); - } - EmitProfilingCounterDecrement(weight); - Label ok; - __ j(positive, &ok, Label::kNear); - __ push(rax); - if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) { - __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); - __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1); - } else { - InterruptStub stub; - __ CallStub(&stub); - } - __ pop(rax); - EmitProfilingCounterReset(); - __ bind(&ok); - } #ifdef DEBUG // Add a label for checking the size of the code used for returning. Label check_exit_codesize; @@ -753,51 +703,61 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, } -void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { - // The variable in the declaration always resides in the current function - // context. - ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); - if (FLAG_debug_code) { - // Check that we're not inside a with or catch context. - __ movq(rbx, FieldOperand(rsi, HeapObject::kMapOffset)); - __ CompareRoot(rbx, Heap::kWithContextMapRootIndex); - __ Check(not_equal, "Declaration in with context."); - __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); - __ Check(not_equal, "Declaration in catch context."); - } -} - - -void FullCodeGenerator::VisitVariableDeclaration( - VariableDeclaration* declaration) { +void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, + VariableMode mode, + FunctionLiteral* function) { // If it was not possible to allocate the variable at compile time, we // need to "declare" it at runtime to make sure it actually exists in the // local context. - VariableProxy* proxy = declaration->proxy(); - VariableMode mode = declaration->mode(); Variable* variable = proxy->var(); - bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; + bool binding_needs_init = (function == NULL) && + (mode == CONST || mode == CONST_HARMONY || mode == LET); switch (variable->location()) { case Variable::UNALLOCATED: - globals_->Add(variable->name()); - globals_->Add(variable->binding_needs_init() - ? isolate()->factory()->the_hole_value() - : isolate()->factory()->undefined_value()); + ++global_count_; break; case Variable::PARAMETER: case Variable::LOCAL: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ movq(StackOperand(variable), result_register()); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); __ movq(StackOperand(variable), kScratchRegister); } break; case Variable::CONTEXT: - if (hole_init) { - Comment cmnt(masm_, "[ VariableDeclaration"); - EmitDebugCheckDeclarationContext(variable); + // The variable in the decl always resides in the current function + // context. + ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); + if (FLAG_debug_code) { + // Check that we're not inside a with or catch context. + __ movq(rbx, FieldOperand(rsi, HeapObject::kMapOffset)); + __ CompareRoot(rbx, Heap::kWithContextMapRootIndex); + __ Check(not_equal, "Declaration in with context."); + __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); + __ Check(not_equal, "Declaration in catch context."); + } + if (function != NULL) { + Comment cmnt(masm_, "[ Declaration"); + VisitForAccumulatorValue(function); + __ movq(ContextOperand(rsi, variable->index()), result_register()); + int offset = Context::SlotOffset(variable->index()); + // We know that we have written a function, which is not a smi. + __ RecordWriteContextSlot(rsi, + offset, + result_register(), + rcx, + kDontSaveFPRegs, + EMIT_REMEMBERED_SET, + OMIT_SMI_CHECK); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); + } else if (binding_needs_init) { + Comment cmnt(masm_, "[ Declaration"); __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); __ movq(ContextOperand(rsi, variable->index()), kScratchRegister); // No write barrier since the hole value is in old space. @@ -806,12 +766,14 @@ void FullCodeGenerator::VisitVariableDeclaration( break; case Variable::LOOKUP: { - Comment cmnt(masm_, "[ VariableDeclaration"); + Comment cmnt(masm_, "[ Declaration"); __ push(rsi); __ Push(variable->name()); // Declaration nodes are always introduced in one of four modes. - ASSERT(mode == VAR || mode == LET || - mode == CONST || mode == CONST_HARMONY); + ASSERT(mode == VAR || + mode == CONST || + mode == CONST_HARMONY || + mode == LET); PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE; __ Push(Smi::FromInt(attr)); @@ -819,7 +781,9 @@ void FullCodeGenerator::VisitVariableDeclaration( // Note: For variables we must not push an initial value (such as // 'undefined') because we may have a (legal) redeclaration and we // must not destroy the current value. - if (hole_init) { + if (function != NULL) { + VisitForStackValue(function); + } else if (binding_needs_init) { __ PushRoot(Heap::kTheHoleValueRootIndex); } else { __ Push(Smi::FromInt(0)); // Indicates no initial value. @@ -831,119 +795,6 @@ void FullCodeGenerator::VisitVariableDeclaration( } -void FullCodeGenerator::VisitFunctionDeclaration( - FunctionDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: { - globals_->Add(variable->name()); - Handle<SharedFunctionInfo> function = - Compiler::BuildFunctionInfo(declaration->fun(), script()); - // Check for stack-overflow exception. - if (function.is_null()) return SetStackOverflow(); - globals_->Add(function); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - VisitForAccumulatorValue(declaration->fun()); - __ movq(StackOperand(variable), result_register()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - EmitDebugCheckDeclarationContext(variable); - VisitForAccumulatorValue(declaration->fun()); - __ movq(ContextOperand(rsi, variable->index()), result_register()); - int offset = Context::SlotOffset(variable->index()); - // We know that we have written a function, which is not a smi. - __ RecordWriteContextSlot(rsi, - offset, - result_register(), - rcx, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), NO_REGISTERS); - break; - } - - case Variable::LOOKUP: { - Comment cmnt(masm_, "[ FunctionDeclaration"); - __ push(rsi); - __ Push(variable->name()); - __ Push(Smi::FromInt(NONE)); - VisitForStackValue(declaration->fun()); - __ CallRuntime(Runtime::kDeclareContextSlot, 4); - break; - } - } -} - - -void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - Handle<JSModule> instance = declaration->module()->interface()->Instance(); - ASSERT(!instance.is_null()); - - switch (variable->location()) { - case Variable::UNALLOCATED: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - globals_->Add(variable->name()); - globals_->Add(instance); - Visit(declaration->module()); - break; - } - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ModuleDeclaration"); - EmitDebugCheckDeclarationContext(variable); - __ Move(ContextOperand(rsi, variable->index()), instance); - Visit(declaration->module()); - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { - VariableProxy* proxy = declaration->proxy(); - Variable* variable = proxy->var(); - switch (variable->location()) { - case Variable::UNALLOCATED: - // TODO(rossberg) - break; - - case Variable::CONTEXT: { - Comment cmnt(masm_, "[ ImportDeclaration"); - EmitDebugCheckDeclarationContext(variable); - // TODO(rossberg) - break; - } - - case Variable::PARAMETER: - case Variable::LOCAL: - case Variable::LOOKUP: - UNREACHABLE(); - } -} - - -void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { - // TODO(rossberg) -} - - void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { // Call the runtime to declare the globals. __ push(rsi); // The context is the first argument. @@ -1005,7 +856,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Record position before stub call for type feedback. SetSourcePosition(clause->position()); Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); - CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); + __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); patch_site.EmitPatchInfo(); __ testq(rax, rax); @@ -1304,7 +1155,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT; - CallIC(ic, mode); + __ call(ic, mode); } @@ -1385,7 +1236,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { __ Move(rcx, var->name()); __ movq(rax, GlobalObjectOperand()); Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); - CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); context()->Plug(rax); break; } @@ -1595,7 +1446,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET, key->id()); + __ call(ic, RelocInfo::CODE_TARGET, key->id()); PrepareForBailoutForId(key->id(), NO_REGISTERS); } else { VisitForEffect(value); @@ -1865,14 +1716,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { Literal* key = prop->key()->AsLiteral(); __ Move(rcx, key->handle()); Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); - CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); + __ call(ic, RelocInfo::CODE_TARGET, prop->id()); } void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); - CallIC(ic, RelocInfo::CODE_TARGET, prop->id()); + __ call(ic, RelocInfo::CODE_TARGET, prop->id()); } @@ -1894,7 +1745,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, __ bind(&stub_call); __ movq(rax, rcx); BinaryOpStub stub(op, mode); - CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); + __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); patch_site.EmitPatchInfo(); __ jmp(&done, Label::kNear); @@ -1943,7 +1794,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, __ pop(rdx); BinaryOpStub stub(op, mode); JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. - CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); + __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); patch_site.EmitPatchInfo(); context()->Plug(rax); } @@ -1984,7 +1835,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); - CallIC(ic); + __ call(ic); break; } case KEYED_PROPERTY: { @@ -1997,7 +1848,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); - CallIC(ic); + __ call(ic); break; } } @@ -2014,7 +1865,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); } else if (op == Token::INIT_CONST) { // Const initializers need a write barrier. ASSERT(!var->IsParameter()); // No const parameters. @@ -2122,7 +1973,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); // If the assignment ends an initialization block, revert to fast case. if (expr->ends_initialization_block()) { @@ -2162,7 +2013,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); // If the assignment ends an initialization block, revert to fast case. if (expr->ends_initialization_block()) { @@ -2196,14 +2047,6 @@ void FullCodeGenerator::VisitProperty(Property* expr) { } -void FullCodeGenerator::CallIC(Handle<Code> code, - RelocInfo::Mode rmode, - unsigned ast_id) { - ic_total_count_++; - __ call(code, rmode, ast_id); -} - - void FullCodeGenerator::EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode) { @@ -2221,7 +2064,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr, // Call the IC initialization code. Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); - CallIC(ic, mode, expr->id()); + __ call(ic, mode, expr->id()); RecordJSReturnSite(expr); // Restore context register. __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); @@ -2254,7 +2097,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); RecordJSReturnSite(expr); // Restore context register. __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); @@ -2273,18 +2116,6 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); - - // Record call targets in unoptimized code, but not in the snapshot. - if (!Serializer::enabled()) { - flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); - Handle<Object> uninitialized = - TypeFeedbackCells::UninitializedSentinel(isolate()); - Handle<JSGlobalPropertyCell> cell = - isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); - RecordTypeFeedbackCell(expr->id(), cell); - __ Move(rbx, cell); - } - CallFunctionStub stub(arg_count, flags); __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); __ CallStub(&stub); @@ -3810,7 +3641,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { RelocInfo::Mode mode = RelocInfo::CODE_TARGET; Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); - CallIC(ic, mode, expr->id()); + __ call(ic, mode, expr->id()); // Restore context register. __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); } else { @@ -3968,7 +3799,7 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, // accumulator register rax. VisitForAccumulatorValue(expr->expression()); SetSourcePosition(expr->position()); - CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); + __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); context()->Plug(rax); } @@ -4089,7 +3920,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ movq(rdx, rax); __ Move(rax, Smi::FromInt(1)); } - CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); + __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); patch_site.EmitPatchInfo(); __ bind(&done); @@ -4123,7 +3954,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->StoreIC_Initialize() : isolate()->builtins()->StoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { @@ -4140,7 +3971,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { Handle<Code> ic = is_classic_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize() : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { @@ -4167,7 +3998,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); // Use a regular load, not a contextual load, to avoid a reference // error. - CallIC(ic); + __ call(ic); PrepareForBailout(expr, TOS_REG); context()->Plug(rax); } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { @@ -4347,7 +4178,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { // Record position and call the compare IC. SetSourcePosition(expr->position()); Handle<Code> ic = CompareIC::GetUninitialized(op); - CallIC(ic, RelocInfo::CODE_TARGET, expr->id()); + __ call(ic, RelocInfo::CODE_TARGET, expr->id()); patch_site.EmitPatchInfo(); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); @@ -4427,8 +4258,7 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) { void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { Scope* declaration_scope = scope()->DeclarationScope(); - if (declaration_scope->is_global_scope() || - declaration_scope->is_module_scope()) { + if (declaration_scope->is_global_scope()) { // Contexts nested in the global context have a canonical empty function // as their closure, not the anonymous closure containing the global // code. Pass a smi sentinel and let the runtime look up the empty diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc index 85e7ac0bf0..2ba2c57f40 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.cc +++ b/deps/v8/src/x64/lithium-codegen-x64.cc @@ -2016,7 +2016,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RECORD_SAFEPOINT_WITH_REGISTERS, 2); ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check)); - LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Move result to a register that survives the end of the // PushSafepointRegisterScope. @@ -2496,28 +2497,24 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register result = ToRegister(instr->result()); - if (instr->hydrogen()->from_inlined()) { - __ lea(result, Operand(rsp, -2 * kPointerSize)); - } else { - // Check for arguments adapter frame. - Label done, adapted; - __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); - __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), - Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - __ j(equal, &adapted, Label::kNear); - - // No arguments adaptor frame. - __ movq(result, rbp); - __ jmp(&done, Label::kNear); + // Check for arguments adapter frame. + Label done, adapted; + __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); + __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), + Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); + __ j(equal, &adapted, Label::kNear); - // Arguments adaptor frame present. - __ bind(&adapted); - __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); + // No arguments adaptor frame. + __ movq(result, rbp); + __ jmp(&done, Label::kNear); - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ bind(&done); - } + // Arguments adaptor frame present. + __ bind(&adapted); + __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); + + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ bind(&done); } @@ -2625,7 +2622,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // Invoke the function. __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( @@ -2643,11 +2640,6 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } -void LCodeGen::DoDrop(LDrop* instr) { - __ Drop(instr->count()); -} - - void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); @@ -2692,8 +2684,7 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { void LCodeGen::CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - RDIState rdi_state) { + CallKind call_kind) { bool can_invoke_directly = !function->NeedsArgumentsAdaption() || function->shared()->formal_parameter_count() == arity; @@ -2701,9 +2692,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, RecordPosition(pointers->position()); if (can_invoke_directly) { - if (rdi_state == RDI_UNINITIALIZED) { - __ LoadHeapObject(rdi, function); - } + __ LoadHeapObject(rdi, function); // Change context if needed. bool change_context = @@ -2748,8 +2737,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { CallKnownFunction(instr->function(), instr->arity(), instr, - CALL_AS_METHOD, - RDI_UNINITIALIZED); + CALL_AS_METHOD); } @@ -3186,21 +3174,13 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ASSERT(ToRegister(instr->function()).is(rdi)); ASSERT(instr->HasPointerMap()); - - if (instr->known_function().is_null()) { - LPointerMap* pointers = instr->pointer_map(); - RecordPosition(pointers->position()); - SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); - ParameterCount count(instr->arity()); - __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); - __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); - } else { - CallKnownFunction(instr->known_function(), - instr->arity(), - instr, - CALL_AS_METHOD, - RDI_CONTAINS_TARGET); - } + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + RecordPosition(pointers->position()); + SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); + ParameterCount count(instr->arity()); + __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); } @@ -3254,11 +3234,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { ASSERT(ToRegister(instr->result()).is(rax)); - CallKnownFunction(instr->target(), - instr->arity(), - instr, - CALL_AS_FUNCTION, - RDI_UNINITIALIZED); + CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); } @@ -3445,20 +3421,16 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { void LCodeGen::DoStoreKeyedFastDoubleElement( LStoreKeyedFastDoubleElement* instr) { XMMRegister value = ToDoubleRegister(instr->value()); + Label have_value; - if (instr->NeedsCanonicalization()) { - Label have_value; - - __ ucomisd(value, value); - __ j(parity_odd, &have_value); // NaN. + __ ucomisd(value, value); + __ j(parity_odd, &have_value); // NaN. - __ Set(kScratchRegister, BitCast<uint64_t>( - FixedDoubleArray::canonical_not_the_hole_nan_as_double())); - __ movq(value, kScratchRegister); - - __ bind(&have_value); - } + __ Set(kScratchRegister, BitCast<uint64_t>( + FixedDoubleArray::canonical_not_the_hole_nan_as_double())); + __ movq(value, kScratchRegister); + __ bind(&have_value); Operand double_store_operand = BuildFastArrayOperand( instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); @@ -3981,21 +3953,12 @@ void LCodeGen::DoCheckMapCommon(Register reg, } -void LCodeGen::DoCheckMaps(LCheckMaps* instr) { +void LCodeGen::DoCheckMap(LCheckMap* instr) { LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); - - Label success; - SmallMapList* map_set = instr->hydrogen()->map_set(); - for (int i = 0; i < map_set->length() - 1; i++) { - Handle<Map> map = map_set->at(i); - __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); - __ j(equal, &success); - } - Handle<Map> map = map_set->last(); - DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr->environment()); - __ bind(&success); + Handle<Map> map = instr->hydrogen()->map(); + DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment()); } @@ -4108,14 +4071,6 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { deferred->entry(), TAG_OBJECT); - __ bind(deferred->exit()); - if (FLAG_debug_code) { - Label is_in_new_space; - __ JumpIfInNewSpace(result, scratch, &is_in_new_space); - __ Abort("Allocated object is not in new-space"); - __ bind(&is_in_new_space); - } - // Load the initial map. Register map = scratch; __ LoadHeapObject(scratch, constructor); @@ -4150,14 +4105,14 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) { __ movq(FieldOperand(result, property_offset), scratch); } } + + __ bind(deferred->exit()); } void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { Register result = ToRegister(instr->result()); Handle<JSFunction> constructor = instr->hydrogen()->constructor(); - Handle<Map> initial_map(constructor->initial_map()); - int instance_size = initial_map->instance_size(); // TODO(3095996): Get rid of this. For now, we need to make the // result register contain a valid pointer because it is already @@ -4165,8 +4120,8 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { __ Set(result, 0); PushSafepointRegistersScope scope(this); - __ Push(Smi::FromInt(instance_size)); - CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); + __ PushHeapObject(constructor); + CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr); __ StoreToSafepointRegisterSlot(result, rax); } @@ -4295,10 +4250,9 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, __ movq(FieldOperand(result, total_offset), rcx); } } else if (elements->IsFixedArray()) { - Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); for (int i = 0; i < elements_length; i++) { int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); - Handle<Object> value(fast_elements->get(i)); + Handle<Object> value = JSObject::GetElement(object, i); if (value->IsJSObject()) { Handle<JSObject> value_object = Handle<JSObject>::cast(value); __ lea(rcx, Operand(result, *offset)); @@ -4322,23 +4276,6 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object, void LCodeGen::DoFastLiteral(LFastLiteral* instr) { int size = instr->hydrogen()->total_size(); - ElementsKind boilerplate_elements_kind = - instr->hydrogen()->boilerplate()->GetElementsKind(); - - // Deopt if the literal boilerplate ElementsKind is of a type different than - // the expected one. The check isn't necessary if the boilerplate has already - // been converted to FAST_ELEMENTS. - if (boilerplate_elements_kind != FAST_ELEMENTS) { - __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); - __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset)); - // Load the map's "bit field 2". - __ movb(rcx, FieldOperand(rcx, Map::kBitField2Offset)); - // Retrieve elements_kind from bit field 2. - __ and_(rcx, Immediate(Map::kElementsKindMask)); - __ cmpb(rcx, Immediate(boilerplate_elements_kind << - Map::kElementsKindShift)); - DeoptimizeIf(not_equal, instr->environment()); - } // Allocate all objects that are part of the literal in one big // allocation. This avoids multiple limit checks. @@ -4637,7 +4574,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { LOperand* key = instr->key(); EmitPushTaggedOperand(obj); EmitPushTaggedOperand(key); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); // Create safepoint generator that will also ensure enough space in the @@ -4655,7 +4592,7 @@ void LCodeGen::DoIn(LIn* instr) { LOperand* key = instr->key(); EmitPushTaggedOperand(key); EmitPushTaggedOperand(obj); - ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); SafepointGenerator safepoint_generator( diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h index 1331fba555..f5045b66a2 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.h +++ b/deps/v8/src/x64/lithium-codegen-x64.h @@ -196,18 +196,12 @@ class LCodeGen BASE_EMBEDDED { int argc, LInstruction* instr); - enum RDIState { - RDI_UNINITIALIZED, - RDI_CONTAINS_TARGET - }; - // Generate a direct call to a known function. Expects the function // to be in rdi. void CallKnownFunction(Handle<JSFunction> function, int arity, LInstruction* instr, - CallKind call_kind, - RDIState rdi_state); + CallKind call_kind); void RecordSafepointWithLazyDeopt(LInstruction* instr, diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc index 3ba0cae7ad..593e778d82 100644 --- a/deps/v8/src/x64/lithium-x64.cc +++ b/deps/v8/src/x64/lithium-x64.cc @@ -110,17 +110,22 @@ void LInstruction::PrintTo(StringStream* stream) { } -void LInstruction::PrintDataTo(StringStream* stream) { +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { stream->Add("= "); - for (int i = 0; i < InputCount(); i++) { + for (int i = 0; i < inputs_.length(); i++) { if (i > 0) stream->Add(" "); - InputAt(i)->PrintTo(stream); + inputs_[i]->PrintTo(stream); } } -void LInstruction::PrintOutputOperandTo(StringStream* stream) { - if (HasResult()) result()->PrintTo(stream); +template<int R, int I, int T> +void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { + for (int i = 0; i < results_.length(); i++) { + if (i > 0) stream->Add(" "); + results_[i]->PrintTo(stream); + } } @@ -722,6 +727,22 @@ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { } +LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id) { + ASSERT(instruction_pending_deoptimization_environment_ == NULL); + ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); + instruction_pending_deoptimization_environment_ = instr; + pending_deoptimization_ast_id_ = ast_id; + return instr; +} + + +void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { + instruction_pending_deoptimization_environment_ = NULL; + pending_deoptimization_ast_id_ = AstNode::kNoNumber; +} + + LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize) { @@ -734,10 +755,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, if (hinstr->HasObservableSideEffects()) { ASSERT(hinstr->next()->IsSimulate()); HSimulate* sim = HSimulate::cast(hinstr->next()); - ASSERT(instruction_pending_deoptimization_environment_ == NULL); - ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); - instruction_pending_deoptimization_environment_ = instr; - pending_deoptimization_ast_id_ = sim->ast_id(); + instr = SetInstructionPendingDeoptimizationEnvironment( + instr, sim->ast_id()); } // If instruction does not have side-effects lazy deoptimization @@ -755,6 +774,12 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, } +LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { + instr->MarkAsSaveDoubles(); + return instr; +} + + LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { ASSERT(!instr->HasPointerMap()); instr->set_pointer_map(new(zone()) LPointerMap(position_)); @@ -1260,7 +1285,6 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { ASSERT(instr->value()->representation().IsInteger32()); ASSERT(instr->representation().IsInteger32()); - if (instr->HasNoUses()) return NULL; LOperand* input = UseRegisterAtStart(instr->value()); LBitNotI* result = new(zone()) LBitNotI(input); return DefineSameAsFirst(result); @@ -1285,12 +1309,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { } -LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { - UNIMPLEMENTED(); - return NULL; -} - - LInstruction* LChunkBuilder::DoMod(HMod* instr) { if (instr->representation().IsInteger32()) { ASSERT(instr->left()->representation().IsInteger32()); @@ -1719,9 +1737,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { } -LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { +LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - LCheckMaps* result = new(zone()) LCheckMaps(value); + LCheckMap* result = new(zone()) LCheckMap(value); return AssignEnvironment(result); } @@ -2223,12 +2241,9 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { if (pending_deoptimization_ast_id_ == instr->ast_id()) { LLazyBailout* lazy_bailout = new(zone()) LLazyBailout; LInstruction* result = AssignEnvironment(lazy_bailout); - // Store the lazy deopt environment with the instruction if needed. Right - // now it is only used for LInstanceOfKnownGlobal. instruction_pending_deoptimization_environment_-> - SetDeferredLazyDeoptimizationEnvironment(result->environment()); - instruction_pending_deoptimization_environment_ = NULL; - pending_deoptimization_ast_id_ = AstNode::kNoNumber; + set_deoptimization_environment(result->environment()); + ClearInstructionPendingDeoptimizationEnvironment(); return result; } @@ -2255,8 +2270,8 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { undefined, instr->call_kind(), instr->is_construct()); - if (instr->arguments_var() != NULL) { - inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject()); + if (instr->arguments() != NULL) { + inner->Bind(instr->arguments(), graph()->GetArgumentsObject()); } current_block_->UpdateEnvironment(inner); chunk_->AddInlinedClosure(instr->closure()); @@ -2265,21 +2280,10 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { - LInstruction* pop = NULL; - - HEnvironment* env = current_block_->last_environment(); - - if (instr->arguments_pushed()) { - int argument_count = env->arguments_environment()->parameter_count(); - pop = new(zone()) LDrop(argument_count); - argument_count_ -= argument_count; - } - HEnvironment* outer = current_block_->last_environment()-> DiscardInlined(false); current_block_->UpdateEnvironment(outer); - - return pop; + return NULL; } diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h index 9083c1f8db..2d8fd2ecce 100644 --- a/deps/v8/src/x64/lithium-x64.h +++ b/deps/v8/src/x64/lithium-x64.h @@ -71,7 +71,7 @@ class LCodeGen; V(CallStub) \ V(CheckFunction) \ V(CheckInstanceType) \ - V(CheckMaps) \ + V(CheckMap) \ V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ @@ -179,8 +179,7 @@ class LCodeGen; V(CheckMapValue) \ V(LoadFieldByIndex) \ V(DateField) \ - V(WrapReceiver) \ - V(Drop) + V(WrapReceiver) #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ @@ -204,15 +203,16 @@ class LInstruction: public ZoneObject { LInstruction() : environment_(NULL), hydrogen_value_(NULL), - is_call_(false) { } + is_call_(false), + is_save_doubles_(false) { } virtual ~LInstruction() { } virtual void CompileToNative(LCodeGen* generator) = 0; virtual const char* Mnemonic() const = 0; virtual void PrintTo(StringStream* stream); - virtual void PrintDataTo(StringStream* stream); - virtual void PrintOutputOperandTo(StringStream* stream); + virtual void PrintDataTo(StringStream* stream) = 0; + virtual void PrintOutputOperandTo(StringStream* stream) = 0; enum Opcode { // Declare a unique enum value for each instruction. @@ -247,12 +247,22 @@ class LInstruction: public ZoneObject { void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } - void MarkAsCall() { is_call_ = true; } + void set_deoptimization_environment(LEnvironment* env) { + deoptimization_environment_.set(env); + } + LEnvironment* deoptimization_environment() const { + return deoptimization_environment_.get(); + } + bool HasDeoptimizationEnvironment() const { + return deoptimization_environment_.is_set(); + } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } + void MarkAsCall() { is_call_ = true; } + void MarkAsSaveDoubles() { is_save_doubles_ = true; } // Interface to the register allocator and iterators. bool IsMarkedAsCall() const { return is_call_; } + bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; } virtual bool HasResult() const = 0; virtual LOperand* result() = 0; @@ -273,7 +283,9 @@ class LInstruction: public ZoneObject { LEnvironment* environment_; SetOncePointer<LPointerMap> pointer_map_; HValue* hydrogen_value_; + SetOncePointer<LEnvironment> deoptimization_environment_; bool is_call_; + bool is_save_doubles_; }; @@ -295,6 +307,9 @@ class LTemplateInstruction: public LInstruction { int TempCount() { return T; } LOperand* TempAt(int i) { return temps_[i]; } + virtual void PrintDataTo(StringStream* stream); + virtual void PrintOutputOperandTo(StringStream* stream); + protected: EmbeddedContainer<LOperand*, R> results_; EmbeddedContainer<LOperand*, I> inputs_; @@ -520,8 +535,9 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { public: + LArgumentsElements() { } + DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") - DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements) }; @@ -815,15 +831,6 @@ class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) Handle<JSFunction> function() const { return hydrogen()->function(); } - LEnvironment* GetDeferredLazyDeoptimizationEnvironment() { - return lazy_deopt_env_; - } - virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { - lazy_deopt_env_ = env; - } - - private: - LEnvironment* lazy_deopt_env_; }; @@ -1351,19 +1358,6 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; -class LDrop: public LTemplateInstruction<0, 0, 0> { - public: - explicit LDrop(int count) : count_(count) { } - - int count() const { return count_; } - - DECLARE_CONCRETE_INSTRUCTION(Drop, "drop") - - private: - int count_; -}; - - class LThisFunction: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function") @@ -1440,7 +1434,6 @@ class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { virtual void PrintDataTo(StringStream* stream); int arity() const { return hydrogen()->argument_count() - 1; } - Handle<JSFunction> known_function() { return hydrogen()->known_function(); } }; @@ -1714,8 +1707,6 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } - - bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; @@ -1866,14 +1857,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> { }; -class LCheckMaps: public LTemplateInstruction<0, 1, 0> { +class LCheckMap: public LTemplateInstruction<0, 1, 0> { public: - explicit LCheckMaps(LOperand* value) { + explicit LCheckMap(LOperand* value) { inputs_[0] = value; } - DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps") - DECLARE_HYDROGEN_ACCESSOR(CheckMaps) + DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") + DECLARE_HYDROGEN_ACCESSOR(CheckMap) }; @@ -2344,6 +2335,11 @@ class LChunkBuilder BASE_EMBEDDED { LInstruction* instr, HInstruction* hinstr, CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); + LInstruction* MarkAsSaveDoubles(LInstruction* instr); + + LInstruction* SetInstructionPendingDeoptimizationEnvironment( + LInstruction* instr, int ast_id); + void ClearInstructionPendingDeoptimizationEnvironment(); LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, int* argument_index_accumulator); diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc index 53becf6c3c..f7db250f9e 100644 --- a/deps/v8/src/x64/macro-assembler-x64.cc +++ b/deps/v8/src/x64/macro-assembler-x64.cc @@ -150,20 +150,6 @@ int MacroAssembler::LoadAddressSize(ExternalReference source) { } -void MacroAssembler::PushAddress(ExternalReference source) { - int64_t address = reinterpret_cast<int64_t>(source.address()); - if (is_int32(address) && !Serializer::enabled()) { - if (emit_debug_code()) { - movq(kScratchRegister, BitCast<int64_t>(kZapValue), RelocInfo::NONE); - } - push(Immediate(static_cast<int32_t>(address))); - return; - } - LoadAddress(kScratchRegister, source); - push(kScratchRegister); -} - - void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { ASSERT(root_array_available_); movq(destination, Operand(kRootRegister, @@ -671,7 +657,7 @@ static int Offset(ExternalReference ref0, ExternalReference ref1) { void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { -#if defined(_WIN64) && !defined(__MINGW64__) +#ifdef _WIN64 // We need to prepare a slot for result handle on stack and put // a pointer to it into 1st arg register. EnterApiExitFrame(arg_stack_space + 1); @@ -719,7 +705,7 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, RelocInfo::RUNTIME_ENTRY); call(rax); -#if defined(_WIN64) && !defined(__MINGW64__) +#ifdef _WIN64 // rax keeps a pointer to v8::Handle, unpack it. movq(rax, Operand(rax, 0)); #endif diff --git a/deps/v8/src/x64/macro-assembler-x64.h b/deps/v8/src/x64/macro-assembler-x64.h index 66587d5319..6bb5cfeb42 100644 --- a/deps/v8/src/x64/macro-assembler-x64.h +++ b/deps/v8/src/x64/macro-assembler-x64.h @@ -127,8 +127,6 @@ class MacroAssembler: public Assembler { // Returns the size of the code generated by LoadAddress. // Used by CallSize(ExternalReference) to find the size of a call. int LoadAddressSize(ExternalReference source); - // Pushes the address of the external reference onto the stack. - void PushAddress(ExternalReference source); // Operations on roots in the root-array. void LoadRoot(Register destination, Heap::RootListIndex index); diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/x64/regexp-macro-assembler-x64.cc index bf232bff9b..837c2543c3 100644 --- a/deps/v8/src/x64/regexp-macro-assembler-x64.cc +++ b/deps/v8/src/x64/regexp-macro-assembler-x64.cc @@ -542,13 +542,9 @@ void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c, void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_equal) { - if (c == 0) { - __ testl(current_character(), Immediate(mask)); - } else { - __ movl(rax, Immediate(mask)); - __ and_(rax, current_character()); - __ cmpl(rax, Immediate(c)); - } + __ movl(rax, current_character()); + __ and_(rax, Immediate(mask)); + __ cmpl(rax, Immediate(c)); BranchOrBacktrack(equal, on_equal); } @@ -556,13 +552,9 @@ void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c, void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, Label* on_not_equal) { - if (c == 0) { - __ testl(current_character(), Immediate(mask)); - } else { - __ movl(rax, Immediate(mask)); - __ and_(rax, current_character()); - __ cmpl(rax, Immediate(c)); - } + __ movl(rax, current_character()); + __ and_(rax, Immediate(mask)); + __ cmpl(rax, Immediate(c)); BranchOrBacktrack(not_equal, on_not_equal); } @@ -580,42 +572,6 @@ void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd( } -void RegExpMacroAssemblerX64::CheckCharacterInRange( - uc16 from, - uc16 to, - Label* on_in_range) { - __ leal(rax, Operand(current_character(), -from)); - __ cmpl(rax, Immediate(to - from)); - BranchOrBacktrack(below_equal, on_in_range); -} - - -void RegExpMacroAssemblerX64::CheckCharacterNotInRange( - uc16 from, - uc16 to, - Label* on_not_in_range) { - __ leal(rax, Operand(current_character(), -from)); - __ cmpl(rax, Immediate(to - from)); - BranchOrBacktrack(above, on_not_in_range); -} - - -void RegExpMacroAssemblerX64::CheckBitInTable( - Handle<ByteArray> table, - Label* on_bit_set) { - __ Move(rax, table); - Register index = current_character(); - if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { - __ movq(rbx, current_character()); - __ and_(rbx, Immediate(kTableMask)); - index = rbx; - } - __ cmpb(FieldOperand(rax, index, times_1, ByteArray::kHeaderSize), - Immediate(0)); - BranchOrBacktrack(not_equal, on_bit_set); -} - - bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { // Range checks (c in min..max) are generally implemented by an unsigned diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.h b/deps/v8/src/x64/regexp-macro-assembler-x64.h index cd24b60981..7102225e64 100644 --- a/deps/v8/src/x64/regexp-macro-assembler-x64.h +++ b/deps/v8/src/x64/regexp-macro-assembler-x64.h @@ -75,14 +75,6 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler { uc16 minus, uc16 mask, Label* on_not_equal); - virtual void CheckCharacterInRange(uc16 from, - uc16 to, - Label* on_in_range); - virtual void CheckCharacterNotInRange(uc16 from, - uc16 to, - Label* on_not_in_range); - virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); - // Checks whether the given offset from the current position is before // the end of the string. virtual void CheckPosition(int cp_offset, Label* on_outside_input); diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc index 5721e9b373..96ff499354 100644 --- a/deps/v8/src/x64/stub-cache-x64.cc +++ b/deps/v8/src/x64/stub-cache-x64.cc @@ -379,7 +379,6 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(receiver); __ push(holder); __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); - __ PushAddress(ExternalReference::isolate_address()); } @@ -394,7 +393,7 @@ static void CompileCallLoadPropertyWithInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()); - __ Set(rax, 6); + __ Set(rax, 5); __ LoadAddress(rbx, ref); CEntryStub stub(1); @@ -403,7 +402,7 @@ static void CompileCallLoadPropertyWithInterceptor( // Number of pointers to be reserved on stack for fast API call. -static const int kFastApiCallArguments = 4; +static const int kFastApiCallArguments = 3; // Reserves space for the extra arguments to API function in the @@ -453,11 +452,10 @@ static void GenerateFastApiCall(MacroAssembler* masm, // -- rsp[16] : api function // (first fast api call extra argument) // -- rsp[24] : api call data - // -- rsp[32] : isolate - // -- rsp[40] : last argument + // -- rsp[32] : last argument // -- ... - // -- rsp[(argc + 4) * 8] : first argument - // -- rsp[(argc + 5) * 8] : receiver + // -- rsp[(argc + 3) * 8] : first argument + // -- rsp[(argc + 4) * 8] : receiver // ----------------------------------- // Get the function and setup the context. Handle<JSFunction> function = optimization.constant_function(); @@ -475,15 +473,11 @@ static void GenerateFastApiCall(MacroAssembler* masm, } else { __ Move(Operand(rsp, 3 * kPointerSize), call_data); } - __ movq(kScratchRegister, ExternalReference::isolate_address()); - __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister); // Prepare arguments. - __ lea(rbx, Operand(rsp, 4 * kPointerSize)); + __ lea(rbx, Operand(rsp, 3 * kPointerSize)); -#if defined(__MINGW64__) - Register arguments_arg = rcx; -#elif defined(_WIN64) +#ifdef _WIN64 // Win64 uses first register--rcx--for returned value. Register arguments_arg = rdx; #else @@ -669,7 +663,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 6); + 5); // Restore the name_ register. __ pop(name_); @@ -1011,15 +1005,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, } else { __ Push(Handle<Object>(callback->data())); } - __ PushAddress(ExternalReference::isolate_address()); // isolate __ push(name_reg); // name // Save a pointer to where we pushed the arguments pointer. // This will be passed as the const AccessorInfo& to the C++ callback. -#if defined(__MINGW64__) - Register accessor_info_arg = rdx; - Register name_arg = rcx; -#elif defined(_WIN64) +#ifdef _WIN64 // Win64 uses first register--rcx--for returned value. Register accessor_info_arg = r8; Register name_arg = rdx; @@ -1032,14 +1022,14 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, __ movq(name_arg, rsp); __ push(scratch2); // Restore return address. - // 4 elements array for v8::Arguments::values_ and handler for name. - const int kStackSpace = 5; + // 3 elements array for v8::Arguments::values_ and handler for name. + const int kStackSpace = 4; // Allocate v8::AccessorInfo in non-GCed stack space. const int kArgStackSpace = 1; __ PrepareCallApiFunction(kArgStackSpace); - __ lea(rax, Operand(name_arg, 4 * kPointerSize)); + __ lea(rax, Operand(name_arg, 3 * kPointerSize)); // v8::AccessorInfo::args_. __ movq(StackSpaceOperand(0), rax); @@ -1196,7 +1186,6 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, __ push(holder_reg); __ Move(holder_reg, callback); __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); - __ PushAddress(ExternalReference::isolate_address()); __ push(holder_reg); __ push(name_reg); __ push(scratch2); // restore return address @@ -1204,7 +1193,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1219,7 +1208,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, ExternalReference ref = ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); - __ TailCallExternalReference(ref, 6, 1); + __ TailCallExternalReference(ref, 5, 1); } } @@ -2011,7 +2000,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( name, depth, &miss); // Move the return address on top of the stack. - __ movq(rax, Operand(rsp, 4 * kPointerSize)); + __ movq(rax, Operand(rsp, 3 * kPointerSize)); __ movq(Operand(rsp, 0 * kPointerSize), rax); GenerateFastApiCall(masm(), optimization, argc); @@ -3132,32 +3121,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( __ jmp(miss_ic, RelocInfo::CODE_TARGET); } - -static void GenerateSmiKeyCheck(MacroAssembler* masm, - Register key, - Register scratch, - XMMRegister xmm_scratch0, - XMMRegister xmm_scratch1, - Label* fail) { - // Check that key is a smi or a heap number containing a smi and branch - // if the check fails. - Label key_ok; - __ JumpIfSmi(key, &key_ok); - __ CheckMap(key, - masm->isolate()->factory()->heap_number_map(), - fail, - DONT_DO_SMI_CHECK); - __ movsd(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset)); - __ cvttsd2si(scratch, xmm_scratch0); - __ cvtlsi2sd(xmm_scratch1, scratch); - __ ucomisd(xmm_scratch1, xmm_scratch0); - __ j(not_equal, fail); - __ j(parity_even, fail); // NaN. - __ Integer32ToSmi(key, scratch); - __ bind(&key_ok); -} - - void KeyedLoadStubCompiler::GenerateLoadExternalArray( MacroAssembler* masm, ElementsKind elements_kind) { @@ -3171,8 +3134,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rax, &miss_force_generic); // Check that the index is in range. __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); @@ -3306,8 +3269,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rcx, &miss_force_generic); // Check that the index is in range. __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); @@ -3408,28 +3371,30 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } else { // Perform float-to-int conversion with truncation (round-to-zero) // behavior. - // Fast path: use machine instruction to convert to int64. If that - // fails (out-of-range), go into the runtime. - __ cvttsd2siq(r8, xmm0); - __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); - __ cmpq(r8, kScratchRegister); - __ j(equal, &slow); + // Convert to int32 and store the low byte/word. + // If the value is NaN or +/-infinity, the result is 0x80000000, + // which is automatically zero when taken mod 2^n, n < 32. // rdx: value (converted to an untagged integer) // rdi: untagged index // rbx: base pointer of external storage switch (elements_kind) { case EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: - __ movb(Operand(rbx, rdi, times_1, 0), r8); + __ cvttsd2si(rdx, xmm0); + __ movb(Operand(rbx, rdi, times_1, 0), rdx); break; case EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: - __ movw(Operand(rbx, rdi, times_2, 0), r8); + __ cvttsd2si(rdx, xmm0); + __ movw(Operand(rbx, rdi, times_2, 0), rdx); break; case EXTERNAL_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS: - __ movl(Operand(rbx, rdi, times_4, 0), r8); + // Convert to int64, so that NaN and infinities become + // 0x8000000000000000, which is zero mod 2^32. + __ cvttsd2siq(rdx, xmm0); + __ movl(Operand(rbx, rdi, times_4, 0), rdx); break; case EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS: @@ -3486,8 +3451,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rax, &miss_force_generic); // Get the elements array. __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); @@ -3528,8 +3493,8 @@ void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rax, &miss_force_generic); // Get the elements array. __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); @@ -3584,8 +3549,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rcx, &miss_force_generic); if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { __ JumpIfNotSmi(rax, &transition_elements_kind); @@ -3726,8 +3691,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - // Check that the key is a smi or a heap number convertible to a smi. - GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); + // Check that the key is a smi. + __ JumpIfNotSmi(rcx, &miss_force_generic); // Get the elements array. __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc index 0b342ff3d9..b1900f9ed3 100644 --- a/deps/v8/test/cctest/test-accessors.cc +++ b/deps/v8/test/cctest/test-accessors.cc @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2009 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -116,8 +116,6 @@ static v8::Handle<v8::Object> x_holder; static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_receiver, info.This()); CHECK_EQ(x_holder, info.Holder()); return v8_num(x_register); @@ -127,8 +125,6 @@ static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { static void XSetter(Local<String> name, Local<Value> value, const AccessorInfo& info) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_holder, info.This()); CHECK_EQ(x_holder, info.Holder()); x_register = value->Int32Value(); @@ -240,15 +236,12 @@ THREADED_TEST(HandleScopePop) { static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name, const AccessorInfo& info) { - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); ApiTestFuzzer::Fuzz(); - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); return v8::Integer::New(17); diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc index e195d14923..769fe7be29 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/test-alloc.cc @@ -34,15 +34,6 @@ using namespace v8::internal; -static inline void SimulateFullSpace(PagedSpace* space) { - int old_linear_size = static_cast<int>(space->limit() - space->top()); - space->Free(space->top(), old_linear_size); - space->SetTop(space->limit(), space->limit()); - space->ResetFreeList(); - space->ClearStats(); -} - - static MaybeObject* AllocateAfterFailures() { static int attempts = 0; if (++attempts < 3) return Failure::RetryAfterGC(); @@ -74,12 +65,24 @@ static MaybeObject* AllocateAfterFailures() { CHECK(!heap->CopyJSObject(JSObject::cast(object))->IsFailure()); // Old data space. - SimulateFullSpace(heap->old_data_space()); + OldSpace* old_data_space = heap->old_data_space(); + static const int kOldDataSpaceFillerSize = ByteArray::SizeFor(0); + while (old_data_space->Available() > kOldDataSpaceFillerSize) { + CHECK(!heap->AllocateByteArray(0, TENURED)->IsFailure()); + } CHECK(!heap->AllocateRawAsciiString(100, TENURED)->IsFailure()); // Old pointer space. - SimulateFullSpace(heap->old_pointer_space()); - CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure()); + OldSpace* old_pointer_space = heap->old_pointer_space(); + static const int kOldPointerSpaceFillerLength = 10000; + static const int kOldPointerSpaceFillerSize = FixedArray::SizeFor( + kOldPointerSpaceFillerLength); + while (old_pointer_space->Available() > kOldPointerSpaceFillerSize) { + CHECK(!heap->AllocateFixedArray(kOldPointerSpaceFillerLength, TENURED)-> + IsFailure()); + } + CHECK(!heap->AllocateFixedArray(kOldPointerSpaceFillerLength, TENURED)-> + IsFailure()); // Large object space. static const int kLargeObjectSpaceFillerLength = 300000; @@ -94,9 +97,14 @@ static MaybeObject* AllocateAfterFailures() { IsFailure()); // Map space. - SimulateFullSpace(heap->map_space()); + MapSpace* map_space = heap->map_space(); + static const int kMapSpaceFillerSize = Map::kSize; + InstanceType instance_type = JS_OBJECT_TYPE; int instance_size = JSObject::kHeaderSize; - CHECK(!heap->AllocateMap(JS_OBJECT_TYPE, instance_size)->IsFailure()); + while (map_space->Available() > kMapSpaceFillerSize) { + CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure()); + } + CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure()); // Test that we can allocate in old pointer space and code space. CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure()); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 8a1e914736..f4ab9ad0df 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -8608,8 +8608,6 @@ static void CheckInterceptorLoadIC(NamedPropertyGetter getter, static v8::Handle<Value> InterceptorLoadICGetter(Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(v8_str("data"), info.Data()); CHECK_EQ(v8_str("x"), name); return v8::Integer::New(42); @@ -9336,8 +9334,6 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, static v8::Handle<Value> FastApiCallback_TrivialSignature( const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); return v8::Integer::New(args[0]->Int32Value() + 1); @@ -9346,8 +9342,6 @@ static v8::Handle<Value> FastApiCallback_TrivialSignature( static v8::Handle<Value> FastApiCallback_SimpleSignature( const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This()->GetPrototype(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); // Note, we're using HasRealNamedProperty instead of Has to avoid @@ -10871,18 +10865,13 @@ THREADED_TEST(NestedHandleScopeAndContexts) { } -static int64_t cast(intptr_t x) { return static_cast<int64_t>(x); } - - THREADED_TEST(ExternalAllocatedMemory) { v8::HandleScope outer; v8::Persistent<Context> env(Context::New()); CHECK(!env.IsEmpty()); - const intptr_t kSize = 1024*1024; - CHECK_EQ(cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize)), - cast(kSize)); - CHECK_EQ(cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize)), - cast(0)); + const int kSize = 1024*1024; + CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize); + CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0); } @@ -12376,46 +12365,6 @@ THREADED_TEST(ForceDeleteIC) { } -TEST(InlinedFunctionAcrossContexts) { - i::FLAG_allow_natives_syntax = true; - v8::HandleScope outer_scope; - v8::Persistent<v8::Context> ctx1 = v8::Context::New(); - v8::Persistent<v8::Context> ctx2 = v8::Context::New(); - ctx1->Enter(); - - { - v8::HandleScope inner_scope; - CompileRun("var G = 42; function foo() { return G; }"); - v8::Local<v8::Value> foo = ctx1->Global()->Get(v8_str("foo")); - ctx2->Enter(); - ctx2->Global()->Set(v8_str("o"), foo); - v8::Local<v8::Value> res = CompileRun( - "function f() { return o(); }" - "for (var i = 0; i < 10; ++i) f();" - "%OptimizeFunctionOnNextCall(f);" - "f();"); - CHECK_EQ(42, res->Int32Value()); - ctx2->Exit(); - v8::Handle<v8::String> G_property = v8::String::New("G"); - CHECK(ctx1->Global()->ForceDelete(G_property)); - ctx2->Enter(); - ExpectString( - "(function() {" - " try {" - " return f();" - " } catch(e) {" - " return e.toString();" - " }" - " })()", - "ReferenceError: G is not defined"); - ctx2->Exit(); - ctx1->Exit(); - ctx1.Dispose(); - } - ctx2.Dispose(); -} - - v8::Persistent<Context> calling_context0; v8::Persistent<Context> calling_context1; v8::Persistent<Context> calling_context2; @@ -12481,16 +12430,19 @@ THREADED_TEST(GetCallingContext) { // Check that a variable declaration with no explicit initialization -// value does shadow an existing property in the prototype chain. +// value does not shadow an existing property in the prototype chain. +// +// This is consistent with Firefox and Safari. +// +// See http://crbug.com/12548. THREADED_TEST(InitGlobalVarInProtoChain) { - i::FLAG_es52_globals = true; v8::HandleScope scope; LocalContext context; // Introduce a variable in the prototype chain. CompileRun("__proto__.x = 42"); - v8::Handle<v8::Value> result = CompileRun("var x = 43; x"); + v8::Handle<v8::Value> result = CompileRun("var x; x"); CHECK(!result->IsUndefined()); - CHECK_EQ(43, result->Int32Value()); + CHECK_EQ(42, result->Int32Value()); } @@ -13995,104 +13947,75 @@ TEST(SourceURLInStackTrace) { } -static void CreateGarbageInOldSpace() { - v8::HandleScope scope; - i::AlwaysAllocateScope always_allocate; - for (int i = 0; i < 1000; i++) { - FACTORY->NewFixedArray(1000, i::TENURED); - } -} - // Test that idle notification can be handled and eventually returns true. -TEST(IdleNotification) { - const intptr_t MB = 1024 * 1024; +// This just checks the contract of the IdleNotification() function, +// and does not verify that it does reasonable work. +THREADED_TEST(IdleNotification) { v8::HandleScope scope; LocalContext env; - intptr_t initial_size = HEAP->SizeOfObjects(); - CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); - CHECK_GT(size_with_garbage, initial_size + MB); - bool finished = false; - for (int i = 0; i < 200 && !finished; i++) { - finished = v8::V8::IdleNotification(); + { + // Create garbage in old-space to generate work for idle notification. + i::AlwaysAllocateScope always_allocate; + for (int i = 0; i < 100; i++) { + FACTORY->NewFixedArray(1000, i::TENURED); + } + } + bool finshed_idle_work = false; + for (int i = 0; i < 100 && !finshed_idle_work; i++) { + finshed_idle_work = v8::V8::IdleNotification(); } - intptr_t final_size = HEAP->SizeOfObjects(); - CHECK(finished); - CHECK_LT(final_size, initial_size + 1); + CHECK(finshed_idle_work); } - -// Test that idle notification can be handled and eventually collects garbage. +// Test that idle notification can be handled and eventually returns true. +// This just checks the contract of the IdleNotification() function, +// and does not verify that it does reasonable work. TEST(IdleNotificationWithSmallHint) { - const intptr_t MB = 1024 * 1024; - const int IdlePauseInMs = 900; v8::HandleScope scope; LocalContext env; - intptr_t initial_size = HEAP->SizeOfObjects(); - CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); - CHECK_GT(size_with_garbage, initial_size + MB); - bool finished = false; - for (int i = 0; i < 200 && !finished; i++) { - finished = v8::V8::IdleNotification(IdlePauseInMs); + { + // Create garbage in old-space to generate work for idle notification. + i::AlwaysAllocateScope always_allocate; + for (int i = 0; i < 100; i++) { + FACTORY->NewFixedArray(1000, i::TENURED); + } + } + intptr_t old_size = HEAP->SizeOfObjects(); + bool finshed_idle_work = false; + bool no_idle_work = v8::V8::IdleNotification(10); + for (int i = 0; i < 200 && !finshed_idle_work; i++) { + finshed_idle_work = v8::V8::IdleNotification(10); } - intptr_t final_size = HEAP->SizeOfObjects(); - CHECK(finished); - CHECK_LT(final_size, initial_size + 1); + intptr_t new_size = HEAP->SizeOfObjects(); + CHECK(finshed_idle_work); + CHECK(no_idle_work || new_size < old_size); } -// Test that idle notification can be handled and eventually collects garbage. +// This just checks the contract of the IdleNotification() function, +// and does not verify that it does reasonable work. TEST(IdleNotificationWithLargeHint) { - const intptr_t MB = 1024 * 1024; - const int IdlePauseInMs = 900; v8::HandleScope scope; LocalContext env; - intptr_t initial_size = HEAP->SizeOfObjects(); - CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); - CHECK_GT(size_with_garbage, initial_size + MB); - bool finished = false; - for (int i = 0; i < 200 && !finished; i++) { - finished = v8::V8::IdleNotification(IdlePauseInMs); + { + // Create garbage in old-space to generate work for idle notification. + i::AlwaysAllocateScope always_allocate; + for (int i = 0; i < 100; i++) { + FACTORY->NewFixedArray(1000, i::TENURED); + } + } + intptr_t old_size = HEAP->SizeOfObjects(); + bool finshed_idle_work = false; + bool no_idle_work = v8::V8::IdleNotification(900); + for (int i = 0; i < 200 && !finshed_idle_work; i++) { + finshed_idle_work = v8::V8::IdleNotification(900); } - intptr_t final_size = HEAP->SizeOfObjects(); - CHECK(finished); - CHECK_LT(final_size, initial_size + 1); + intptr_t new_size = HEAP->SizeOfObjects(); + CHECK(finshed_idle_work); + CHECK(no_idle_work || new_size < old_size); } -TEST(Regress2107) { - const intptr_t MB = 1024 * 1024; - const int kShortIdlePauseInMs = 100; - const int kLongIdlePauseInMs = 1000; - v8::HandleScope scope; - LocalContext env; - intptr_t initial_size = HEAP->SizeOfObjects(); - // Send idle notification to start a round of incremental GCs. - v8::V8::IdleNotification(kShortIdlePauseInMs); - // Emulate 7 page reloads. - for (int i = 0; i < 7; i++) { - v8::Persistent<v8::Context> ctx = v8::Context::New(); - ctx->Enter(); - CreateGarbageInOldSpace(); - ctx->Exit(); - ctx.Dispose(); - v8::V8::ContextDisposedNotification(); - v8::V8::IdleNotification(kLongIdlePauseInMs); - } - // Create garbage and check that idle notification still collects it. - CreateGarbageInOldSpace(); - intptr_t size_with_garbage = HEAP->SizeOfObjects(); - CHECK_GT(size_with_garbage, initial_size + MB); - bool finished = false; - for (int i = 0; i < 200 && !finished; i++) { - finished = v8::V8::IdleNotification(kShortIdlePauseInMs); - } - intptr_t final_size = HEAP->SizeOfObjects(); - CHECK_LT(final_size, initial_size + 1); -} - static uint32_t* stack_limit; static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { @@ -16502,94 +16425,3 @@ TEST(PrimaryStubCache) { StubCacheHelper(false); } - -static int fatal_error_callback_counter = 0; -static void CountingErrorCallback(const char* location, const char* message) { - printf("CountingErrorCallback(\"%s\", \"%s\")\n", location, message); - fatal_error_callback_counter++; -} - - -TEST(StaticGetters) { - v8::HandleScope scope; - LocalContext context; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - i::Handle<i::Object> undefined_value = FACTORY->undefined_value(); - CHECK(*v8::Utils::OpenHandle(*v8::Undefined()) == *undefined_value); - CHECK(*v8::Utils::OpenHandle(*v8::Undefined(isolate)) == *undefined_value); - i::Handle<i::Object> null_value = FACTORY->null_value(); - CHECK(*v8::Utils::OpenHandle(*v8::Null()) == *null_value); - CHECK(*v8::Utils::OpenHandle(*v8::Null(isolate)) == *null_value); - i::Handle<i::Object> true_value = FACTORY->true_value(); - CHECK(*v8::Utils::OpenHandle(*v8::True()) == *true_value); - CHECK(*v8::Utils::OpenHandle(*v8::True(isolate)) == *true_value); - i::Handle<i::Object> false_value = FACTORY->false_value(); - CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value); - CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value); - - // Test after-death behavior. - CHECK(i::Internals::IsInitialized(isolate)); - CHECK_EQ(0, fatal_error_callback_counter); - v8::V8::SetFatalErrorHandler(CountingErrorCallback); - v8::Utils::ReportApiFailure("StaticGetters()", "Kill V8"); - i::Isolate::Current()->TearDown(); - CHECK(!i::Internals::IsInitialized(isolate)); - CHECK_EQ(1, fatal_error_callback_counter); - CHECK(v8::Undefined().IsEmpty()); - CHECK_EQ(2, fatal_error_callback_counter); - CHECK(v8::Undefined(isolate).IsEmpty()); - CHECK_EQ(3, fatal_error_callback_counter); - CHECK(v8::Null().IsEmpty()); - CHECK_EQ(4, fatal_error_callback_counter); - CHECK(v8::Null(isolate).IsEmpty()); - CHECK_EQ(5, fatal_error_callback_counter); - CHECK(v8::True().IsEmpty()); - CHECK_EQ(6, fatal_error_callback_counter); - CHECK(v8::True(isolate).IsEmpty()); - CHECK_EQ(7, fatal_error_callback_counter); - CHECK(v8::False().IsEmpty()); - CHECK_EQ(8, fatal_error_callback_counter); - CHECK(v8::False(isolate).IsEmpty()); - CHECK_EQ(9, fatal_error_callback_counter); -} - - -TEST(IsolateEmbedderData) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - CHECK_EQ(NULL, isolate->GetData()); - CHECK_EQ(NULL, ISOLATE->GetData()); - static void* data1 = reinterpret_cast<void*>(0xacce55ed); - isolate->SetData(data1); - CHECK_EQ(data1, isolate->GetData()); - CHECK_EQ(data1, ISOLATE->GetData()); - static void* data2 = reinterpret_cast<void*>(0xdecea5ed); - ISOLATE->SetData(data2); - CHECK_EQ(data2, isolate->GetData()); - CHECK_EQ(data2, ISOLATE->GetData()); - ISOLATE->TearDown(); - CHECK_EQ(data2, isolate->GetData()); - CHECK_EQ(data2, ISOLATE->GetData()); -} - - -TEST(StringEmpty) { - v8::HandleScope scope; - LocalContext context; - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - i::Handle<i::Object> empty_string = FACTORY->empty_symbol(); - CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string); - CHECK(*v8::Utils::OpenHandle(*v8::String::Empty(isolate)) == *empty_string); - - // Test after-death behavior. - CHECK(i::Internals::IsInitialized(isolate)); - CHECK_EQ(0, fatal_error_callback_counter); - v8::V8::SetFatalErrorHandler(CountingErrorCallback); - v8::Utils::ReportApiFailure("StringEmpty()", "Kill V8"); - i::Isolate::Current()->TearDown(); - CHECK(!i::Internals::IsInitialized(isolate)); - CHECK_EQ(1, fatal_error_callback_counter); - CHECK(v8::String::Empty().IsEmpty()); - CHECK_EQ(2, fatal_error_callback_counter); - CHECK(v8::String::Empty(isolate).IsEmpty()); - CHECK_EQ(3, fatal_error_callback_counter); -} diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index e40f406c3c..ffa845813f 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -5013,10 +5013,7 @@ static void ThreadedMessageHandler(const v8::Debug::Message& message) { if (IsBreakEventMessage(print_buffer)) { // Check that we are inside the while loop. int source_line = GetSourceLineFromBreakEventMessage(print_buffer); - // TODO(2047): This should really be 8 <= source_line <= 13; but we - // currently have an off-by-one error when calculating the source - // position corresponding to the program counter at the debug break. - CHECK(7 <= source_line && source_line <= 13); + CHECK(8 <= source_line && source_line <= 13); threaded_debugging_barriers.barrier_2.Wait(); } } diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc index e6bdc9f505..aa733c70bc 100644 --- a/deps/v8/test/cctest/test-decls.cc +++ b/deps/v8/test/cctest/test-decls.cc @@ -521,7 +521,6 @@ class ExistsInPrototypeContext: public DeclarationContext { TEST(ExistsInPrototype) { - i::FLAG_es52_globals = true; HandleScope scope; // Sanity check to make sure that the holder of the interceptor @@ -536,17 +535,17 @@ TEST(ExistsInPrototype) { { ExistsInPrototypeContext context; context.Check("var x; x", - 0, // get + 1, // get 0, - 0, // declaration - EXPECT_RESULT, Undefined()); + 1, // declaration + EXPECT_EXCEPTION); } { ExistsInPrototypeContext context; context.Check("var x = 0; x", 0, 0, - 0, // declaration + 1, // declaration EXPECT_RESULT, Number::New(0)); } @@ -554,7 +553,7 @@ TEST(ExistsInPrototype) { context.Check("const x; x", 0, 0, - 0, // declaration + 1, // declaration EXPECT_RESULT, Undefined()); } @@ -562,7 +561,7 @@ TEST(ExistsInPrototype) { context.Check("const x = 0; x", 0, 0, - 0, // declaration + 1, // declaration EXPECT_RESULT, Number::New(0)); } } @@ -584,14 +583,13 @@ class AbsentInPrototypeContext: public DeclarationContext { TEST(AbsentInPrototype) { - i::FLAG_es52_globals = true; HandleScope scope; { AbsentInPrototypeContext context; context.Check("if (false) { var x = 0; }; x", 0, 0, - 0, // declaration + 1, // declaration EXPECT_RESULT, Undefined()); } } diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index c6332e249b..da85eb933e 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -264,7 +264,6 @@ TEST(DisasmX64) { ExternalReference after_break_target = ExternalReference(Debug_Address::AfterBreakTarget(), assm.isolate()); - USE(after_break_target); #endif // ENABLE_DEBUGGER_SUPPORT __ jmp(ic, RelocInfo::CODE_TARGET); __ nop(); diff --git a/deps/v8/test/cctest/test-double.cc b/deps/v8/test/cctest/test-double.cc index 6ef42c64dd..3594a4fe32 100644 --- a/deps/v8/test/cctest/test-double.cc +++ b/deps/v8/test/cctest/test-double.cc @@ -112,6 +112,21 @@ TEST(IsInfinite) { } +TEST(IsNan) { + CHECK(Double(OS::nan_value()).IsNan()); + uint64_t other_nan = V8_2PART_UINT64_C(0xFFFFFFFF, 00000001); + CHECK(Double(other_nan).IsNan()); + CHECK(!Double(V8_INFINITY).IsNan()); + CHECK(!Double(-V8_INFINITY).IsNan()); + CHECK(!Double(0.0).IsNan()); + CHECK(!Double(-0.0).IsNan()); + CHECK(!Double(1.0).IsNan()); + CHECK(!Double(-1.0).IsNan()); + uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); + CHECK(!Double(min_double64).IsNan()); +} + + TEST(Sign) { CHECK_EQ(1, Double(1.0).Sign()); CHECK_EQ(1, Double(V8_INFINITY).Sign()); diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 3ac17414a0..a56f250c2a 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -2,14 +2,11 @@ // // Tests for heap profiler -#include <ctype.h> - #include "v8.h" #include "cctest.h" #include "heap-profiler.h" #include "snapshot.h" -#include "debug.h" #include "utils-inl.h" #include "../include/v8-profiler.h" @@ -112,13 +109,13 @@ TEST(HeapSnapshot) { // Verify, that JS global object of env2 has '..2' properties. const v8::HeapGraphNode* a2_node = - GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2"); + GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); CHECK_NE(NULL, a2_node); CHECK_NE( - NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1")); + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); CHECK_NE( - NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2")); - CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2")); + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); + CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); // Paint all nodes reachable from global object. NamedEntriesDetector det; @@ -140,13 +137,12 @@ TEST(HeapSnapshotObjectSizes) { CompileRun( "function X(a, b) { this.a = a; this.b = b; }\n" "x = new X(new X(), new X());\n" - "dummy = new X();\n" "(function() { x.a.a = x.b; })();"); const v8::HeapSnapshot* snapshot = v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* x = - GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); CHECK_NE(NULL, x); const v8::HeapGraphNode* x1 = GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); @@ -173,7 +169,7 @@ TEST(BoundFunctionInSnapshot) { v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* f = - GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "boundFunction"); CHECK(f); CHECK_EQ(v8::String::New("native_bind"), f->GetName()); const v8::HeapGraphNode* bindings = @@ -237,15 +233,15 @@ TEST(HeapSnapshotCodeObjects) { const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* compiled = - GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); CHECK_NE(NULL, compiled); CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); const v8::HeapGraphNode* lazy = - GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); CHECK_NE(NULL, lazy); CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); const v8::HeapGraphNode* anonymous = - GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous"); CHECK_NE(NULL, anonymous); CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); v8::String::AsciiValue anonymous_name(anonymous->GetName()); @@ -297,9 +293,9 @@ TEST(HeapSnapshotHeapNumbers) { const v8::HeapSnapshot* snapshot = v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); - CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a")); + CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); const v8::HeapGraphNode* b = - GetProperty(global, v8::HeapGraphEdge::kProperty, "b"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); CHECK_NE(NULL, b); CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); } @@ -317,10 +313,10 @@ TEST(HeapSnapshotSlicedString) { v8::HeapProfiler::TakeSnapshot(v8_str("strings")); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* parent_string = - GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "parent_string"); CHECK_NE(NULL, parent_string); const v8::HeapGraphNode* child_string = - GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "child_string"); CHECK_NE(NULL, child_string); const v8::HeapGraphNode* parent = GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); @@ -348,12 +344,12 @@ TEST(HeapSnapshotInternalReferences) { } -// Trying to introduce a check helper for uint32_t causes many +// Trying to introduce a check helper for uint64_t causes many // overloading ambiguities, so it seems easier just to cast // them to a signed type. -#define CHECK_EQ_SNAPSHOT_OBJECT_ID(a, b) \ - CHECK_EQ(static_cast<int32_t>(a), static_cast<int32_t>(b)) -#define CHECK_NE_SNAPSHOT_OBJECT_ID(a, b) \ +#define CHECK_EQ_UINT64_T(a, b) \ + CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b)) +#define CHECK_NE_UINT64_T(a, b) \ CHECK((a) != (b)) // NOLINT TEST(HeapEntryIdsAndArrayShift) { @@ -382,24 +378,31 @@ TEST(HeapEntryIdsAndArrayShift) { const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); + CHECK_NE_UINT64_T(0, global1->GetId()); + CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); const v8::HeapGraphNode* a1 = GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); CHECK_NE(NULL, a1); + const v8::HeapGraphNode* e1 = + GetProperty(a1, v8::HeapGraphEdge::kHidden, "1"); + CHECK_NE(NULL, e1); const v8::HeapGraphNode* k1 = - GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements"); + GetProperty(e1, v8::HeapGraphEdge::kInternal, "elements"); CHECK_NE(NULL, k1); const v8::HeapGraphNode* a2 = GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); CHECK_NE(NULL, a2); + const v8::HeapGraphNode* e2 = + GetProperty(a2, v8::HeapGraphEdge::kHidden, "1"); + CHECK_NE(NULL, e2); const v8::HeapGraphNode* k2 = - GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements"); + GetProperty(e2, v8::HeapGraphEdge::kInternal, "elements"); CHECK_NE(NULL, k2); - CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); + CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId()); + CHECK_EQ_UINT64_T(e1->GetId(), e2->GetId()); + CHECK_EQ_UINT64_T(k1->GetId(), k2->GetId()); } TEST(HeapEntryIdsAndGC) { @@ -411,56 +414,50 @@ TEST(HeapEntryIdsAndGC) { "function B(x) { this.x = x; }\n" "var a = new A();\n" "var b = new B(a);"); - v8::Local<v8::String> s1_str = v8_str("s1"); - v8::Local<v8::String> s2_str = v8_str("s2"); const v8::HeapSnapshot* snapshot1 = - v8::HeapProfiler::TakeSnapshot(s1_str); + v8::HeapProfiler::TakeSnapshot(v8_str("s1")); HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); const v8::HeapSnapshot* snapshot2 = - v8::HeapProfiler::TakeSnapshot(s2_str); - - CHECK_GT(snapshot1->GetMaxSnapshotJSObjectId(), 7000); - CHECK(snapshot1->GetMaxSnapshotJSObjectId() <= - snapshot2->GetMaxSnapshotJSObjectId()); + v8::HeapProfiler::TakeSnapshot(v8_str("s2")); const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); + CHECK_NE_UINT64_T(0, global1->GetId()); + CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); const v8::HeapGraphNode* A1 = GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); CHECK_NE(NULL, A1); const v8::HeapGraphNode* A2 = GetProperty(global2, v8::HeapGraphEdge::kProperty, "A"); CHECK_NE(NULL, A2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, A1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(A1->GetId(), A2->GetId()); + CHECK_NE_UINT64_T(0, A1->GetId()); + CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId()); const v8::HeapGraphNode* B1 = GetProperty(global1, v8::HeapGraphEdge::kProperty, "B"); CHECK_NE(NULL, B1); const v8::HeapGraphNode* B2 = GetProperty(global2, v8::HeapGraphEdge::kProperty, "B"); CHECK_NE(NULL, B2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, B1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(B1->GetId(), B2->GetId()); + CHECK_NE_UINT64_T(0, B1->GetId()); + CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId()); const v8::HeapGraphNode* a1 = GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); CHECK_NE(NULL, a1); const v8::HeapGraphNode* a2 = GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); CHECK_NE(NULL, a2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, a1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); + CHECK_NE_UINT64_T(0, a1->GetId()); + CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId()); const v8::HeapGraphNode* b1 = GetProperty(global1, v8::HeapGraphEdge::kProperty, "b"); CHECK_NE(NULL, b1); const v8::HeapGraphNode* b2 = GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); CHECK_NE(NULL, b2); - CHECK_NE_SNAPSHOT_OBJECT_ID(0, b1->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(b1->GetId(), b2->GetId()); + CHECK_NE_UINT64_T(0, b1->GetId()); + CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); } @@ -511,7 +508,7 @@ TEST(HeapEntryDominator) { const v8::HeapGraphNode* global = GetGlobalObject(snapshot); CHECK_NE(NULL, global); const v8::HeapGraphNode* node6 = - GetProperty(global, v8::HeapGraphEdge::kProperty, "node6"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); CHECK_NE(NULL, node6); const v8::HeapGraphNode* node5 = GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); @@ -554,14 +551,9 @@ class TestJSONStream : public v8::OutputStream { memcpy(chunk.start(), buffer, chars_written); return kContinue; } - virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) { - ASSERT(false); - return kAbort; - } void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } int eos_signaled() { return eos_signaled_; } int size() { return buffer_.size(); } - private: i::Collector<char> buffer_; int eos_signaled_; @@ -615,37 +607,42 @@ TEST(HeapSnapshotJSONSerialization) { env->Global()->Get(v8_str("parsed"))->ToObject(); CHECK(parsed_snapshot->Has(v8_str("snapshot"))); CHECK(parsed_snapshot->Has(v8_str("nodes"))); - CHECK(parsed_snapshot->Has(v8_str("edges"))); CHECK(parsed_snapshot->Has(v8_str("strings"))); // Get node and edge "member" offsets. v8::Local<v8::Value> meta_analysis_result = CompileRun( - "var meta = parsed.snapshot.meta;\n" - "var edges_index_offset = meta.node_fields.indexOf('edges_index');\n" - "var node_fields_count = meta.node_fields.length;\n" - "var edge_fields_count = meta.edge_fields.length;\n" - "var edge_type_offset = meta.edge_fields.indexOf('type');\n" - "var edge_name_offset = meta.edge_fields.indexOf('name_or_index');\n" - "var edge_to_node_offset = meta.edge_fields.indexOf('to_node');\n" + "var parsed_meta = parsed.nodes[0];\n" + "var children_count_offset =" + " parsed_meta.fields.indexOf('children_count');\n" + "var children_offset =" + " parsed_meta.fields.indexOf('children');\n" + "var children_meta =" + " parsed_meta.types[children_offset];\n" + "var child_fields_count = children_meta.fields.length;\n" + "var child_type_offset =" + " children_meta.fields.indexOf('type');\n" + "var child_name_offset =" + " children_meta.fields.indexOf('name_or_index');\n" + "var child_to_node_offset =" + " children_meta.fields.indexOf('to_node');\n" "var property_type =" - " meta.edge_types[edge_type_offset].indexOf('property');\n" + " children_meta.types[child_type_offset].indexOf('property');\n" "var shortcut_type =" - " meta.edge_types[edge_type_offset].indexOf('shortcut');\n" - "parsed.nodes.concat(0, 0, 0, 0, 0, 0, parsed.edges.length);"); + " children_meta.types[child_type_offset].indexOf('shortcut');"); CHECK(!meta_analysis_result.IsEmpty()); // A helper function for processing encoded nodes. CompileRun( "function GetChildPosByProperty(pos, prop_name, prop_type) {\n" " var nodes = parsed.nodes;\n" - " var edges = parsed.edges;\n" " var strings = parsed.strings;\n" - " for (var i = nodes[pos + edges_index_offset],\n" - " count = nodes[pos + node_fields_count + edges_index_offset];\n" - " i < count; i += edge_fields_count) {\n" - " if (edges[i + edge_type_offset] === prop_type\n" - " && strings[edges[i + edge_name_offset]] === prop_name)\n" - " return edges[i + edge_to_node_offset];\n" + " for (var i = 0,\n" + " count = nodes[pos + children_count_offset] * child_fields_count;\n" + " i < count; i += child_fields_count) {\n" + " var child_pos = pos + children_offset + i;\n" + " if (nodes[child_pos + child_type_offset] === prop_type\n" + " && strings[nodes[child_pos + child_name_offset]] === prop_name)\n" + " return nodes[child_pos + child_to_node_offset];\n" " }\n" " return null;\n" "}\n"); @@ -654,9 +651,8 @@ TEST(HeapSnapshotJSONSerialization) { "GetChildPosByProperty(\n" " GetChildPosByProperty(\n" " GetChildPosByProperty(" - " parsed.edges[parsed.nodes[edges_index_offset]" - " + edge_to_node_offset]," - " \"b\", property_type),\n" + " parsed.nodes[1 + children_offset + child_to_node_offset]," + " \"b\",shortcut_type),\n" " \"x\", property_type)," " \"s\", property_type)"); CHECK(!string_obj_pos_val.IsEmpty()); @@ -689,200 +685,6 @@ TEST(HeapSnapshotJSONSerializationAborting) { CHECK_EQ(0, stream.eos_signaled()); } -namespace { - -class TestStatsStream : public v8::OutputStream { - public: - TestStatsStream() - : eos_signaled_(0), - updates_written_(0), - entries_count_(0), - entries_size_(0), - intervals_count_(0), - first_interval_index_(-1) { } - TestStatsStream(const TestStatsStream& stream) - : v8::OutputStream(stream), - eos_signaled_(stream.eos_signaled_), - updates_written_(stream.updates_written_), - entries_count_(stream.entries_count_), - entries_size_(stream.entries_size_), - intervals_count_(stream.intervals_count_), - first_interval_index_(stream.first_interval_index_) { } - virtual ~TestStatsStream() {} - virtual void EndOfStream() { ++eos_signaled_; } - virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { - ASSERT(false); - return kAbort; - } - virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* buffer, - int updates_written) { - ++intervals_count_; - ASSERT(updates_written); - updates_written_ += updates_written; - entries_count_ = 0; - if (first_interval_index_ == -1 && updates_written != 0) - first_interval_index_ = buffer[0].index; - for (int i = 0; i < updates_written; ++i) { - entries_count_ += buffer[i].count; - entries_size_ += buffer[i].size; - } - - return kContinue; - } - int eos_signaled() { return eos_signaled_; } - int updates_written() { return updates_written_; } - uint32_t entries_count() const { return entries_count_; } - uint32_t entries_size() const { return entries_size_; } - int intervals_count() const { return intervals_count_; } - int first_interval_index() const { return first_interval_index_; } - - private: - int eos_signaled_; - int updates_written_; - uint32_t entries_count_; - uint32_t entries_size_; - int intervals_count_; - int first_interval_index_; -}; - -} // namespace - -static TestStatsStream GetHeapStatsUpdate() { - TestStatsStream stream; - v8::HeapProfiler::PushHeapObjectsStats(&stream); - CHECK_EQ(1, stream.eos_signaled()); - return stream; -} - - -TEST(HeapSnapshotObjectsStats) { - v8::HandleScope scope; - LocalContext env; - - v8::HeapProfiler::StartHeapObjectsTracking(); - // We have to call GC 5 times. In other case the garbage will be - // the reason of flakiness. - for (int i = 0; i < 5; ++i) { - HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); - } - - { - // Single chunk of data expected in update. Initial data. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_LT(0, stats_update.entries_size()); - CHECK_EQ(0, stats_update.first_interval_index()); - } - - // No data expected in update because nothing has happened. - CHECK_EQ(0, GetHeapStatsUpdate().updates_written()); - { - v8::HandleScope inner_scope_1; - v8_str("string1"); - { - // Single chunk of data with one new entry expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_LT(0, stats_update.entries_size()); - CHECK_EQ(1, stats_update.entries_count()); - CHECK_EQ(2, stats_update.first_interval_index()); - } - - // No data expected in update because nothing happened. - CHECK_EQ(0, GetHeapStatsUpdate().updates_written()); - - { - v8::HandleScope inner_scope_2; - v8_str("string2"); - - uint32_t entries_size; - { - v8::HandleScope inner_scope_3; - v8_str("string3"); - v8_str("string4"); - - { - // Single chunk of data with three new entries expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_LT(0, entries_size = stats_update.entries_size()); - CHECK_EQ(3, stats_update.entries_count()); - CHECK_EQ(4, stats_update.first_interval_index()); - } - } - - { - // Single chunk of data with two left entries expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_GT(entries_size, stats_update.entries_size()); - CHECK_EQ(1, stats_update.entries_count()); - // Two strings from forth interval were released. - CHECK_EQ(4, stats_update.first_interval_index()); - } - } - - { - // Single chunk of data with 0 left entries expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_EQ(0, stats_update.entries_size()); - CHECK_EQ(0, stats_update.entries_count()); - // The last string from forth interval was released. - CHECK_EQ(4, stats_update.first_interval_index()); - } - } - { - // Single chunk of data with 0 left entries expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_EQ(0, stats_update.entries_size()); - CHECK_EQ(0, stats_update.entries_count()); - // The only string from the second interval was released. - CHECK_EQ(2, stats_update.first_interval_index()); - } - - v8::Local<v8::Array> array = v8::Array::New(); - CHECK_EQ(0, array->Length()); - // Force array's buffer allocation. - array->Set(2, v8_num(7)); - - uint32_t entries_size; - { - // Single chunk of data with 2 entries expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - CHECK_EQ(1, stats_update.updates_written()); - CHECK_LT(0, entries_size = stats_update.entries_size()); - // They are the array and its buffer. - CHECK_EQ(2, stats_update.entries_count()); - CHECK_EQ(8, stats_update.first_interval_index()); - } - - for (int i = 0; i < 100; ++i) - array->Set(i, v8_num(i)); - - { - // Single chunk of data with 1 entry expected in update. - TestStatsStream stats_update = GetHeapStatsUpdate(); - CHECK_EQ(1, stats_update.intervals_count()); - // The first interval was changed because old buffer was collected. - // The second interval was changed because new buffer was allocated. - CHECK_EQ(2, stats_update.updates_written()); - CHECK_LT(entries_size, stats_update.entries_size()); - CHECK_EQ(2, stats_update.entries_count()); - CHECK_EQ(8, stats_update.first_interval_index()); - } - - v8::HeapProfiler::StopHeapObjectsTracking(); -} - static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, const v8::HeapGraphNode* node, @@ -893,7 +695,7 @@ static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, const v8::HeapGraphEdge* prop = node->GetChild(i); const v8::HeapGraphNode* child = snapshot->GetNodeById(prop->GetToNode()->GetId()); - CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); + CHECK_EQ_UINT64_T(prop->GetToNode()->GetId(), child->GetId()); CHECK_EQ(prop->GetToNode(), child); CheckChildrenIds(snapshot, child, level + 1, max_level); } @@ -913,42 +715,6 @@ TEST(HeapSnapshotGetNodeById) { } -TEST(HeapSnapshotGetSnapshotObjectId) { - v8::HandleScope scope; - LocalContext env; - CompileRun("globalObject = {};\n"); - const v8::HeapSnapshot* snapshot = - v8::HeapProfiler::TakeSnapshot(v8_str("get_snapshot_object_id")); - const v8::HeapGraphNode* global = GetGlobalObject(snapshot); - const v8::HeapGraphNode* global_object = - GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); - CHECK(global_object); - - v8::Local<v8::Value> globalObjectHandle = - env->Global()->Get(v8::String::New("globalObject")); - CHECK(!globalObjectHandle.IsEmpty()); - CHECK(globalObjectHandle->IsObject()); - - v8::SnapshotObjectId id = - v8::HeapProfiler::GetSnapshotObjectId(globalObjectHandle); - CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), - id); - CHECK_EQ(static_cast<int>(id), global_object->GetId()); -} - - -TEST(HeapSnapshotUnknownSnapshotObjectId) { - v8::HandleScope scope; - LocalContext env; - CompileRun("globalObject = {};\n"); - const v8::HeapSnapshot* snapshot = - v8::HeapProfiler::TakeSnapshot(v8_str("unknown_object_id")); - const v8::HeapGraphNode* node = - snapshot->GetNodeById(v8::HeapProfiler::kUnknownObjectId); - CHECK_EQ(NULL, node); -} - - namespace { class TestActivityControl : public v8::ActivityControl { @@ -1187,8 +953,9 @@ TEST(HeapSnapshotImplicitReferences) { v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs")); const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); + // Use kShortcut type to skip intermediate JSGlobalPropertyCell const v8::HeapGraphNode* obj0 = GetProperty( - global_object, v8::HeapGraphEdge::kProperty, "root_object"); + global_object, v8::HeapGraphEdge::kShortcut, "root_object"); CHECK(obj0); CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); const v8::HeapGraphNode* obj1 = GetProperty( @@ -1361,7 +1128,7 @@ TEST(GetHeapValue) { env->Global()->GetPrototype().As<v8::Object>(); CHECK(js_global == global->GetHeapValue()); const v8::HeapGraphNode* obj = GetProperty( - global, v8::HeapGraphEdge::kProperty, "a"); + global, v8::HeapGraphEdge::kShortcut, "a"); CHECK(obj->GetHeapValue()->IsObject()); v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); CHECK(js_obj == obj->GetHeapValue()); @@ -1390,7 +1157,7 @@ TEST(GetHeapValueForDeletedObject) { v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* obj = GetProperty( - global, v8::HeapGraphEdge::kProperty, "a"); + global, v8::HeapGraphEdge::kShortcut, "a"); const v8::HeapGraphNode* prop = GetProperty( obj, v8::HeapGraphEdge::kProperty, "p"); { @@ -1477,7 +1244,7 @@ TEST(FastCaseGetter) { const v8::HeapGraphNode* global = GetGlobalObject(snapshot); CHECK_NE(NULL, global); const v8::HeapGraphNode* obj1 = - GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1"); CHECK_NE(NULL, obj1); const v8::HeapGraphNode* getterFunction = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); @@ -1559,7 +1326,7 @@ TEST(SfiAndJsFunctionWeakRefs) { const v8::HeapGraphNode* global = GetGlobalObject(snapshot); CHECK_NE(NULL, global); const v8::HeapGraphNode* fun = - GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); + GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); CHECK(HasWeakEdge(fun)); const v8::HeapGraphNode* shared = GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); @@ -1567,30 +1334,6 @@ TEST(SfiAndJsFunctionWeakRefs) { } -TEST(NoDebugObjectInSnapshot) { - v8::HandleScope scope; - LocalContext env; - - v8::internal::Isolate::Current()->debug()->Load(); - CompileRun("foo = {};"); - const v8::HeapSnapshot* snapshot = - v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); - const v8::HeapGraphNode* root = snapshot->GetRoot(); - int globals_count = 0; - for (int i = 0; i < root->GetChildrenCount(); ++i) { - const v8::HeapGraphEdge* edge = root->GetChild(i); - if (edge->GetType() == v8::HeapGraphEdge::kShortcut) { - ++globals_count; - const v8::HeapGraphNode* global = edge->GetToNode(); - const v8::HeapGraphNode* foo = - GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); - CHECK_NE(NULL, foo); - } - } - CHECK_EQ(1, globals_count); -} - - TEST(PersistentHandleCount) { v8::HandleScope scope; LocalContext env; @@ -1623,44 +1366,3 @@ TEST(PersistentHandleCount) { p_BBB.Dispose(); CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); } - - -TEST(AllStrongGcRootsHaveNames) { - v8::HandleScope scope; - LocalContext env; - - CompileRun("foo = {};"); - const v8::HeapSnapshot* snapshot = - v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); - const v8::HeapGraphNode* gc_roots = GetNode( - snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); - CHECK_NE(NULL, gc_roots); - const v8::HeapGraphNode* strong_roots = GetNode( - gc_roots, v8::HeapGraphNode::kObject, "(Strong roots)"); - CHECK_NE(NULL, strong_roots); - for (int i = 0; i < strong_roots->GetChildrenCount(); ++i) { - const v8::HeapGraphEdge* edge = strong_roots->GetChild(i); - CHECK_EQ(v8::HeapGraphEdge::kInternal, edge->GetType()); - v8::String::AsciiValue name(edge->GetName()); - CHECK(isalpha(**name)); - } -} - - -TEST(NoRefsToNonEssentialEntries) { - v8::HandleScope scope; - LocalContext env; - CompileRun("global_object = {};\n"); - const v8::HeapSnapshot* snapshot = - v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); - const v8::HeapGraphNode* global = GetGlobalObject(snapshot); - const v8::HeapGraphNode* global_object = - GetProperty(global, v8::HeapGraphEdge::kProperty, "global_object"); - CHECK_NE(NULL, global_object); - const v8::HeapGraphNode* properties = - GetProperty(global_object, v8::HeapGraphEdge::kInternal, "properties"); - CHECK_EQ(NULL, properties); - const v8::HeapGraphNode* elements = - GetProperty(global_object, v8::HeapGraphEdge::kInternal, "elements"); - CHECK_EQ(NULL, elements); -} diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index 72079dc2ae..f97bf17219 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -1214,9 +1214,7 @@ TEST(TestSizeOfObjects) { // The heap size should go back to initial size after a full GC, even // though sweeping didn't finish yet. HEAP->CollectAllGarbage(Heap::kNoGCFlags); - - // Normally sweeping would not be complete here, but no guarantees. - + CHECK(!HEAP->old_pointer_space()->IsSweepingComplete()); CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects())); // Advancing the sweeper step-wise should not change the heap size. @@ -1266,9 +1264,9 @@ static void FillUpNewSpace(NewSpace* new_space) { v8::HandleScope scope; AlwaysAllocateScope always_allocate; intptr_t available = new_space->EffectiveCapacity() - new_space->Size(); - intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1; + intptr_t number_of_fillers = (available / FixedArray::SizeFor(1000)) - 10; for (intptr_t i = 0; i < number_of_fillers; i++) { - CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(32, NOT_TENURED))); + CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(1000, NOT_TENURED))); } } @@ -1277,13 +1275,6 @@ TEST(GrowAndShrinkNewSpace) { InitializeVM(); NewSpace* new_space = HEAP->new_space(); - if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { - // The max size cannot exceed the reserved size, since semispaces must be - // always within the reserved space. We can't test new space growing and - // shrinking if the reserved size is the same as the minimum (initial) size. - return; - } - // Explicitly growing should double the space capacity. intptr_t old_capacity, new_capacity; old_capacity = new_space->Capacity(); @@ -1324,14 +1315,6 @@ TEST(GrowAndShrinkNewSpace) { TEST(CollectingAllAvailableGarbageShrinksNewSpace) { InitializeVM(); - - if (HEAP->ReservedSemiSpaceSize() == HEAP->InitialSemiSpaceSize()) { - // The max size cannot exceed the reserved size, since semispaces must be - // always within the reserved space. We can't test new space growing and - // shrinking if the reserved size is the same as the minimum (initial) size. - return; - } - v8::HandleScope scope; NewSpace* new_space = HEAP->new_space(); intptr_t old_capacity, new_capacity; @@ -1651,15 +1634,6 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { while (!marking->IsStopped() && !marking->IsComplete()) { marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); } - if (!marking->IsStopped() || marking->should_hurry()) { - // We don't normally finish a GC via Step(), we normally finish by - // setting the stack guard and then do the final steps in the stack - // guard interrupt. But here we didn't ask for that, and there is no - // JS code running to trigger the interrupt, so we explicitly finalize - // here. - HEAP->CollectAllGarbage(Heap::kNoGCFlags, - "Test finalizing incremental mark-sweep"); - } CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age()); CHECK_EQ(0, f->shared()->opt_count()); @@ -1706,32 +1680,3 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { CHECK_EQ(0, f->shared()->opt_count()); CHECK_EQ(0, f->shared()->code()->profiler_ticks()); } - - -// Test that HAllocateObject will always return an object in new-space. -TEST(OptimizedAllocationAlwaysInNewSpace) { - i::FLAG_allow_natives_syntax = true; - InitializeVM(); - if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return; - v8::HandleScope scope; - - FillUpNewSpace(HEAP->new_space()); - AlwaysAllocateScope always_allocate; - v8::Local<v8::Value> res = CompileRun( - "function c(x) {" - " this.x = x;" - " for (var i = 0; i < 32; i++) {" - " this['x' + i] = x;" - " }" - "}" - "function f(x) { return new c(x); };" - "f(1); f(2); f(3);" - "%OptimizeFunctionOnNextCall(f);" - "f(4);"); - CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value()); - - Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); - - CHECK(HEAP->InNewSpace(*o)); -} diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc index 83a576d367..973af19662 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/test-mark-compact.cc @@ -534,15 +534,15 @@ TEST(BootUpMemoryUse) { intptr_t booted_memory = MemoryInUse(); if (sizeof(initial_memory) == 8) { if (v8::internal::Snapshot::IsEnabled()) { - CHECK_LE(booted_memory - initial_memory, 3600 * 1024); // 3396. + CHECK_LE(booted_memory - initial_memory, 6686 * 1024); // 6476. } else { - CHECK_LE(booted_memory - initial_memory, 3600 * 1024); // 3432. + CHECK_LE(booted_memory - initial_memory, 6809 * 1024); // 6628. } } else { if (v8::internal::Snapshot::IsEnabled()) { - CHECK_LE(booted_memory - initial_memory, 2600 * 1024); // 2484. + CHECK_LE(booted_memory - initial_memory, 6532 * 1024); // 6388. } else { - CHECK_LE(booted_memory - initial_memory, 2950 * 1024); // 2844 + CHECK_LE(booted_memory - initial_memory, 6940 * 1024); // 6456 } } } diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index e89e6cddc9..d941d0f7b0 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -504,10 +504,7 @@ static RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) { return NULL; Handle<String> pattern = isolate->factory()-> NewStringFromUtf8(CStrVector(input)); - Handle<String> sample_subject = - isolate->factory()->NewStringFromUtf8(CStrVector("")); - RegExpEngine::Compile( - &compile_data, false, multiline, pattern, sample_subject, is_ascii); + RegExpEngine::Compile(&compile_data, false, multiline, pattern, is_ascii); return compile_data.node; } @@ -1590,7 +1587,7 @@ TEST(CharClassDifference) { ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); ZoneList<CharacterRange>* base = new ZoneList<CharacterRange>(1); base->Add(CharacterRange::Everything()); - Vector<const int> overlay = CharacterRange::GetWordBounds(); + Vector<const uc16> overlay = CharacterRange::GetWordBounds(); ZoneList<CharacterRange>* included = NULL; ZoneList<CharacterRange>* excluded = NULL; CharacterRange::Split(base, overlay, &included, &excluded); @@ -1599,7 +1596,7 @@ TEST(CharClassDifference) { if (in_base) { bool in_overlay = false; for (int j = 0; !in_overlay && j < overlay.length(); j += 2) { - if (overlay[j] <= i && i < overlay[j+1]) + if (overlay[j] <= i && i <= overlay[j+1]) in_overlay = true; } CHECK_EQ(in_overlay, InClass(i, included)); @@ -1672,6 +1669,16 @@ TEST(CanonicalizeCharacterSets) { ASSERT_EQ(30, list->at(0).to()); } +// Checks whether a character is in the set represented by a list of ranges. +static bool CharacterInSet(ZoneList<CharacterRange>* set, uc16 value) { + for (int i = 0; i < set->length(); i++) { + CharacterRange range = set->at(i); + if (range.from() <= value && value <= range.to()) { + return true; + } + } + return false; +} TEST(CharacterRangeMerge) { v8::internal::V8::Initialize(NULL); @@ -1758,6 +1765,67 @@ TEST(CharacterRangeMerge) { ZoneList<CharacterRange> first_only(4); ZoneList<CharacterRange> second_only(4); ZoneList<CharacterRange> both(4); + + // Merge one direction. + CharacterRange::Merge(&l1, &l2, &first_only, &second_only, &both); + + CHECK(CharacterRange::IsCanonical(&first_only)); + CHECK(CharacterRange::IsCanonical(&second_only)); + CHECK(CharacterRange::IsCanonical(&both)); + + for (uc16 i = 0; i < offset; i++) { + bool in_first = CharacterInSet(&l1, i); + bool in_second = CharacterInSet(&l2, i); + CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); + CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); + CHECK((in_first && in_second) == CharacterInSet(&both, i)); + } + + first_only.Clear(); + second_only.Clear(); + both.Clear(); + + // Merge other direction. + CharacterRange::Merge(&l2, &l1, &second_only, &first_only, &both); + + CHECK(CharacterRange::IsCanonical(&first_only)); + CHECK(CharacterRange::IsCanonical(&second_only)); + CHECK(CharacterRange::IsCanonical(&both)); + + for (uc16 i = 0; i < offset; i++) { + bool in_first = CharacterInSet(&l1, i); + bool in_second = CharacterInSet(&l2, i); + CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); + CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); + CHECK((in_first && in_second) == CharacterInSet(&both, i)); + } + + first_only.Clear(); + second_only.Clear(); + both.Clear(); + + // Merge but don't record all combinations. + CharacterRange::Merge(&l1, &l2, NULL, NULL, &both); + + CHECK(CharacterRange::IsCanonical(&both)); + + for (uc16 i = 0; i < offset; i++) { + bool in_first = CharacterInSet(&l1, i); + bool in_second = CharacterInSet(&l2, i); + CHECK((in_first && in_second) == CharacterInSet(&both, i)); + } + + // Merge into same set. + ZoneList<CharacterRange> all(4); + CharacterRange::Merge(&l1, &l2, &all, &all, &all); + + CHECK(CharacterRange::IsCanonical(&all)); + + for (uc16 i = 0; i < offset; i++) { + bool in_first = CharacterInSet(&l1, i); + bool in_second = CharacterInSet(&l2, i); + CHECK((in_first || in_second) == CharacterInSet(&all, i)); + } } diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc index 0e957048ee..92de2a60fa 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/test-spaces.cc @@ -140,8 +140,8 @@ TEST(MemoryAllocator) { heap->MaxReserved(), OLD_POINTER_SPACE, NOT_EXECUTABLE); - Page* first_page = memory_allocator->AllocatePage( - faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE); + Page* first_page = + memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE); first_page->InsertAfter(faked_space.anchor()->prev_page()); CHECK(first_page->is_valid()); @@ -153,8 +153,8 @@ TEST(MemoryAllocator) { } // Again, we should get n or n - 1 pages. - Page* other = memory_allocator->AllocatePage( - faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE); + Page* other = + memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE); CHECK(other->is_valid()); total_pages++; other->InsertAfter(first_page); diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index d86886f9be..e11349bc85 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -587,88 +587,3 @@ TEST(SliceFromSlice) { CHECK(SlicedString::cast(*string)->parent()->IsSeqString()); CHECK_EQ("cdefghijklmnopqrstuvwx", *(string->ToCString())); } - - -TEST(AsciiArrayJoin) { - // Set heap limits. - static const int K = 1024; - v8::ResourceConstraints constraints; - constraints.set_max_young_space_size(256 * K); - constraints.set_max_old_space_size(4 * K * K); - v8::SetResourceConstraints(&constraints); - - // String s is made of 2^17 = 131072 'c' characters and a is an array - // starting with 'bad', followed by 2^14 times the string s. That means the - // total length of the concatenated strings is 2^31 + 3. So on 32bit systems - // summing the lengths of the strings (as Smis) overflows and wraps. - static const char* join_causing_out_of_memory = - "var two_14 = Math.pow(2, 14);" - "var two_17 = Math.pow(2, 17);" - "var s = Array(two_17 + 1).join('c');" - "var a = ['bad'];" - "for (var i = 1; i <= two_14; i++) a.push(s);" - "a.join("");"; - - v8::HandleScope scope; - LocalContext context; - v8::V8::IgnoreOutOfMemoryException(); - v8::Local<v8::Script> script = - v8::Script::Compile(v8::String::New(join_causing_out_of_memory)); - v8::Local<v8::Value> result = script->Run(); - - // Check for out of memory state. - CHECK(result.IsEmpty()); - CHECK(context->HasOutOfMemoryException()); -} - - -static void CheckException(const char* source) { - // An empty handle is returned upon exception. - CHECK(CompileRun(source).IsEmpty()); -} - - -TEST(RobustSubStringStub) { - // This tests whether the SubStringStub can handle unsafe arguments. - // If not recognized, those unsafe arguments lead to out-of-bounds reads. - FLAG_allow_natives_syntax = true; - InitializeVM(); - HandleScope scope; - v8::Local<v8::Value> result; - Handle<String> string; - CompileRun("var short = 'abcdef';"); - - // Invalid indices. - CheckException("%_SubString(short, 0, 10000);"); - CheckException("%_SubString(short, -1234, 5);"); - CheckException("%_SubString(short, 5, 2);"); - // Special HeapNumbers. - CheckException("%_SubString(short, 1, Infinity);"); - CheckException("%_SubString(short, NaN, 5);"); - // String arguments. - CheckException("%_SubString(short, '2', '5');"); - // Ordinary HeapNumbers can be handled (in runtime). - result = CompileRun("%_SubString(short, Math.sqrt(4), 5.1);"); - string = v8::Utils::OpenHandle(v8::String::Cast(*result)); - CHECK_EQ("cde", *(string->ToCString())); - - CompileRun("var long = 'abcdefghijklmnopqrstuvwxyz';"); - // Invalid indices. - CheckException("%_SubString(long, 0, 10000);"); - CheckException("%_SubString(long, -1234, 17);"); - CheckException("%_SubString(long, 17, 2);"); - // Special HeapNumbers. - CheckException("%_SubString(long, 1, Infinity);"); - CheckException("%_SubString(long, NaN, 17);"); - // String arguments. - CheckException("%_SubString(long, '2', '17');"); - // Ordinary HeapNumbers within bounds can be handled (in runtime). - result = CompileRun("%_SubString(long, Math.sqrt(4), 17.1);"); - string = v8::Utils::OpenHandle(v8::String::Cast(*result)); - CHECK_EQ("cdefghijklmnopq", *(string->ToCString())); - - // Test that out-of-bounds substring of a slice fails when the indices - // would have been valid for the underlying string. - CompileRun("var slice = long.slice(1, 15);"); - CheckException("%_SubString(slice, 0, 17);"); -} diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc index cebabaa97e..1aa57e3081 100644 --- a/deps/v8/test/cctest/test-thread-termination.cc +++ b/deps/v8/test/cctest/test-thread-termination.cc @@ -255,10 +255,6 @@ TEST(TerminateMultipleV8ThreadsDefaultIsolate) { threads[i]->Join(); delete threads[i]; } - { - v8::Locker locker; - v8::Locker::StopPreemption(); - } delete semaphore; semaphore = NULL; diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc index 7bba7b6486..56d593628a 100644 --- a/deps/v8/test/cctest/test-weakmaps.cc +++ b/deps/v8/test/cctest/test-weakmaps.cc @@ -48,11 +48,11 @@ static Handle<JSWeakMap> AllocateJSWeakMap() { static void PutIntoWeakMap(Handle<JSWeakMap> weakmap, Handle<JSObject> key, - Handle<Object> value) { + int value) { Handle<ObjectHashTable> table = PutIntoObjectHashTable( Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())), Handle<JSObject>(JSObject::cast(*key)), - value); + Handle<Smi>(Smi::FromInt(value))); weakmap->set_table(*table); } @@ -65,7 +65,6 @@ static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { TEST(Weakness) { - FLAG_incremental_marking = false; LocalContext context; v8::HandleScope scope; Handle<JSWeakMap> weakmap = AllocateJSWeakMap(); @@ -84,9 +83,7 @@ TEST(Weakness) { // Put entry into weak map. { v8::HandleScope scope; - PutIntoWeakMap(weakmap, - Handle<JSObject>(JSObject::cast(*key)), - Handle<Smi>(Smi::FromInt(23))); + PutIntoWeakMap(weakmap, Handle<JSObject>(JSObject::cast(*key)), 23); } CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); @@ -136,7 +133,7 @@ TEST(Shrinking) { Handle<Map> map = FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); for (int i = 0; i < 32; i++) { Handle<JSObject> object = FACTORY->NewJSObjectFromMap(map); - PutIntoWeakMap(weakmap, object, Handle<Smi>(Smi::FromInt(i))); + PutIntoWeakMap(weakmap, object, i); } } @@ -155,72 +152,3 @@ TEST(Shrinking) { // Check shrunk capacity. CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity()); } - - -// Test that weak map values on an evacuation candidate which are not reachable -// by other paths are correctly recorded in the slots buffer. -TEST(Regress2060a) { - FLAG_always_compact = true; - LocalContext context; - v8::HandleScope scope; - Handle<JSFunction> function = - FACTORY->NewFunction(FACTORY->function_symbol(), FACTORY->null_value()); - Handle<JSObject> key = FACTORY->NewJSObject(function); - Handle<JSWeakMap> weakmap = AllocateJSWeakMap(); - - // Start second old-space page so that values land on evacuation candidate. - Page* first_page = HEAP->old_pointer_space()->anchor()->next_page(); - FACTORY->NewFixedArray(900 * KB / kPointerSize, TENURED); - - // Fill up weak map with values on an evacuation candidate. - { - v8::HandleScope scope; - for (int i = 0; i < 32; i++) { - Handle<JSObject> object = FACTORY->NewJSObject(function, TENURED); - CHECK(!HEAP->InNewSpace(object->address())); - CHECK(!first_page->Contains(object->address())); - PutIntoWeakMap(weakmap, key, object); - } - } - - // Force compacting garbage collection. - CHECK(FLAG_always_compact); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); -} - - -// Test that weak map keys on an evacuation candidate which are reachable by -// other strong paths are correctly recorded in the slots buffer. -TEST(Regress2060b) { - FLAG_always_compact = true; -#ifdef DEBUG - FLAG_verify_heap = true; -#endif - LocalContext context; - v8::HandleScope scope; - Handle<JSFunction> function = - FACTORY->NewFunction(FACTORY->function_symbol(), FACTORY->null_value()); - - // Start second old-space page so that keys land on evacuation candidate. - Page* first_page = HEAP->old_pointer_space()->anchor()->next_page(); - FACTORY->NewFixedArray(900 * KB / kPointerSize, TENURED); - - // Fill up weak map with keys on an evacuation candidate. - Handle<JSObject> keys[32]; - for (int i = 0; i < 32; i++) { - keys[i] = FACTORY->NewJSObject(function, TENURED); - CHECK(!HEAP->InNewSpace(keys[i]->address())); - CHECK(!first_page->Contains(keys[i]->address())); - } - Handle<JSWeakMap> weakmap = AllocateJSWeakMap(); - for (int i = 0; i < 32; i++) { - PutIntoWeakMap(weakmap, keys[i], Handle<Smi>(Smi::FromInt(i))); - } - - // Force compacting garbage collection. The subsequent collections are used - // to verify that key references were actually updated. - CHECK(FLAG_always_compact); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); - HEAP->CollectAllGarbage(Heap::kNoGCFlags); -} diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py index b2eabc44eb..f1387e8a4f 100644 --- a/deps/v8/test/cctest/testcfg.py +++ b/deps/v8/test/cctest/testcfg.py @@ -53,6 +53,8 @@ class CcTestCase(test.TestCase): serialization_file = join('obj', 'test', self.mode, 'serdes') else: serialization_file = join('obj', 'serdes') + if not exists(join(self.context.buildspace, 'obj')): + os.makedirs(join(self.context.buildspace, 'obj')) serialization_file += '_' + self.GetName() serialization_file = join(self.context.buildspace, serialization_file) serialization_file += ''.join(self.variant_flags).replace('-', '_') diff --git a/deps/v8/test/mjsunit/array-bounds-check-removal.js b/deps/v8/test/mjsunit/array-bounds-check-removal.js deleted file mode 100644 index 81064aa237..0000000000 --- a/deps/v8/test/mjsunit/array-bounds-check-removal.js +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --expose-gc - -var a = new Int32Array(1024); - -function test_base(base,cond) { - a[base + 1] = 1; - a[base + 4] = 2; - a[base + 3] = 3; - a[base + 2] = 4; - a[base + 4] = base + 4; - if (cond) { - a[base + 1] = 1; - a[base + 2] = 2; - a[base + 2] = 3; - a[base + 2] = 4; - a[base + 4] = base + 4; - } else { - a[base + 6] = 1; - a[base + 4] = 2; - a[base + 3] = 3; - a[base + 2] = 4; - a[base + 4] = base - 4; - } -} - -function check_test_base(base,cond) { - if (cond) { - assertEquals(1, a[base + 1]); - assertEquals(4, a[base + 2]); - assertEquals(base + 4, a[base + 4]); - } else { - assertEquals(1, a[base + 6]); - assertEquals(3, a[base + 3]); - assertEquals(4, a[base + 2]); - assertEquals(base - 4, a[base + 4]); - } -} - - -function test_minus(base,cond) { - a[base - 1] = 1; - a[base - 2] = 2; - a[base + 4] = 3; - a[base] = 4; - a[base + 4] = base + 4; - if (cond) { - a[base - 4] = 1; - a[base + 5] = 2; - a[base + 3] = 3; - a[base + 2] = 4; - a[base + 4] = base + 4; - } else { - a[base + 6] = 1; - a[base + 4] = 2; - a[base + 3] = 3; - a[base + 2] = 4; - a[base + 4] = base - 4; - } -} - -function check_test_minus(base,cond) { - if (cond) { - assertEquals(2, a[base + 5]); - assertEquals(3, a[base + 3]); - assertEquals(4, a[base + 2]); - assertEquals(base + 4, a[base + 4]); - } else { - assertEquals(1, a[base + 6]); - assertEquals(3, a[base + 3]); - assertEquals(4, a[base + 2]); - assertEquals(base - 4, a[base + 4]); - } -} - -test_base(1,true); -test_base(2,true); -test_base(1,false); -test_base(2,false); -%OptimizeFunctionOnNextCall(test_base); -test_base(3,true); -check_test_base(3,true); -test_base(3,false); -check_test_base(3,false); - -test_minus(5,true); -test_minus(6,true); -%OptimizeFunctionOnNextCall(test_minus); -test_minus(7,true); -check_test_minus(7,true); -test_minus(7,false); -check_test_minus(7,false); - -// Optimization status: -// YES: 1 -// NO: 2 -// ALWAYS: 3 -// NEVER: 4 - -if (false) { -test_base(5,true); -test_base(6,true); -test_base(5,false); -test_base(6,false); -%OptimizeFunctionOnNextCall(test_base); -test_base(-2,true); -assertTrue(%GetOptimizationStatus(test_base) != 1); - -test_base(5,true); -test_base(6,true); -test_base(5,false); -test_base(6,false); -%OptimizeFunctionOnNextCall(test_base); -test_base(2048,true); -assertTrue(%GetOptimizationStatus(test_base) != 1); -} - -gc(); - diff --git a/deps/v8/test/mjsunit/big-array-literal.js b/deps/v8/test/mjsunit/big-array-literal.js index a0fad7c2ee..8e0ff87277 100644 --- a/deps/v8/test/mjsunit/big-array-literal.js +++ b/deps/v8/test/mjsunit/big-array-literal.js @@ -25,6 +25,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// On MacOS, this test needs a stack size of at least 538 kBytes. +// Flags: --stack-size=600 + // Test that we can make large object literals that work. // Also test that we can attempt to make even larger object literals without // crashing. diff --git a/deps/v8/test/mjsunit/compiler/alloc-object-huge.js b/deps/v8/test/mjsunit/compiler/alloc-object-huge.js index 0b202f7580..d6d9f1b721 100644 --- a/deps/v8/test/mjsunit/compiler/alloc-object-huge.js +++ b/deps/v8/test/mjsunit/compiler/alloc-object-huge.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --inline-construct --max-inlined-source-size=999999 --max-inlined-nodes=999999 --max-inlined-nodes-cumulative=999999 +// Flags: --allow-natives-syntax --inline-construct --nolimit-inlining // Test that huge constructors (more than 256 this assignments) are // handled correctly. diff --git a/deps/v8/test/mjsunit/compiler/inline-arguments.js b/deps/v8/test/mjsunit/compiler/inline-arguments.js index f8a247608b..b6adf7f6cc 100644 --- a/deps/v8/test/mjsunit/compiler/inline-arguments.js +++ b/deps/v8/test/mjsunit/compiler/inline-arguments.js @@ -113,70 +113,3 @@ F4(1); %OptimizeFunctionOnNextCall(test_adaptation); test_adaptation(); })(); - -// Test arguments access from the inlined function. -function uninlinable(v) { - assertEquals(0, v); - try { } catch (e) { } - return 0; -} - -function toarr_inner() { - var a = arguments; - var marker = a[0]; - uninlinable(uninlinable(0, 0), marker.x); - - var r = new Array(); - for (var i = a.length - 1; i >= 1; i--) { - r.push(a[i]); - } - - return r; -} - -function toarr1(marker, a, b, c) { - return toarr_inner(marker, a / 2, b / 2, c / 2); -} - -function toarr2(marker, a, b, c) { - var x = 0; - return uninlinable(uninlinable(0, 0), - x = toarr_inner(marker, a / 2, b / 2, c / 2)), x; -} - -function test_toarr(toarr) { - var marker = { x: 0 }; - assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6)); - assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6)); - %OptimizeFunctionOnNextCall(toarr); - assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6)); - delete marker.x; - assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6)); -} - -test_toarr(toarr1); -test_toarr(toarr2); - -// Test that arguments access from inlined function uses correct values. -(function () { - function inner(x, y) { - "use strict"; - x = 10; - y = 20; - for (var i = 0; i < 1; i++) { - for (var j = 1; j <= arguments.length; j++) { - return arguments[arguments.length - j]; - } - } - } - - function outer(x, y) { - return inner(x, y); - } - - assertEquals(2, outer(1, 2)); - assertEquals(2, outer(1, 2)); - assertEquals(2, outer(1, 2)); - %OptimizeFunctionOnNextCall(outer); - assertEquals(2, outer(1, 2)); -})(); diff --git a/deps/v8/test/mjsunit/compiler/literals.js b/deps/v8/test/mjsunit/compiler/literals.js index 8607cd9595..e910bb3c6a 100644 --- a/deps/v8/test/mjsunit/compiler/literals.js +++ b/deps/v8/test/mjsunit/compiler/literals.js @@ -36,38 +36,38 @@ assertEquals(8, eval("6;'abc';8")); // Characters just outside the ranges of hex-escapes. // "/" comes just before "0". -assertThrows('"\\x1/"'); -assertThrows('"\\u111/"'); +assertEquals("x1/", "\x1/"); +assertEquals("u111/", "\u111/"); assertEquals("\\x1/", RegExp("\\x1/").source); assertEquals("\\u111/", RegExp("\\u111/").source); // ":" comes just after "9". -assertThrows('"\\x1:"'); -assertThrows('"\\u111:"'); +assertEquals("x1:", "\x1:"); +assertEquals("u111:", "\u111:"); assertEquals("\\x1:", /\x1:/.source); assertEquals("\\u111:", /\u111:/.source); // "`" comes just before "a". -assertThrows('"\\x1`"'); -assertThrows('"\\u111`"'); +assertEquals("x1`", "\x1`"); +assertEquals("u111`", "\u111`"); assertEquals("\\x1`", /\x1`/.source); assertEquals("\\u111`", /\u111`/.source); // "g" comes just before "f". -assertThrows('"\\x1g"'); -assertThrows('"\\u111g"'); +assertEquals("x1g", "\x1g"); +assertEquals("u111g", "\u111g"); assertEquals("\\x1g", /\x1g/.source); assertEquals("\\u111g", /\u111g/.source); // "@" comes just before "A". -assertThrows('"\\x1@"'); -assertThrows('"\\u111@"'); +assertEquals("x1@", "\x1@"); +assertEquals("u111@", "\u111@"); assertEquals("\\x1@", /\x1@/.source); assertEquals("\\u111@", /\u111@/.source); // "G" comes just after "F". -assertThrows('"\\x1G"'); -assertThrows('"\\u111G"'); +assertEquals("x1G", "\x1G"); +assertEquals("u111G", "\u111G"); assertEquals("\\x1G", /\x1G/.source); assertEquals("\\u111G", /\u111G/.source); diff --git a/deps/v8/test/mjsunit/compiler/optimize-bitnot.js b/deps/v8/test/mjsunit/compiler/optimize-bitnot.js deleted file mode 100644 index 28315a4fe2..0000000000 --- a/deps/v8/test/mjsunit/compiler/optimize-bitnot.js +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax - -function f(x) { - return ~~x; -} - -f(42); -f(42); -%OptimizeFunctionOnNextCall(f); -assertEquals(42, f(42)); -assertEquals(42, f(42.5)); -assertEquals(1/0, 1/f(-0)); -assertEquals(-1, f(0xffffffff)); -assertEquals(0, f(undefined)); -assertEquals(0, f("abc")); diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js index efbb2cc8ca..cf25c0c095 100644 --- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js +++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js @@ -148,9 +148,20 @@ function listener(event, exec_state, event_data, data) { assertFalse(frame.isConstructCall()); } - if (i > 4) { - assertFalse(frame.isOptimizedFrame()); - assertFalse(frame.isInlinedFrame()); + // When function f is optimized (1 means YES, see runtime.cc) we + // expect an optimized frame for f with g1, g2 and g3 inlined. + if (%GetOptimizationStatus(f) == 1) { + if (i == 1 || i == 2 || i == 3) { + assertTrue(frame.isOptimizedFrame()); + assertTrue(frame.isInlinedFrame()); + assertEquals(4 - i, frame.inlinedFrameIndex()); + } else if (i == 4) { + assertTrue(frame.isOptimizedFrame()); + assertFalse(frame.isInlinedFrame()); + } else { + assertFalse(frame.isOptimizedFrame()); + assertFalse(frame.isInlinedFrame()); + } } } diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js index 9c56a12be2..c88a683a8c 100644 --- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js +++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js @@ -138,9 +138,20 @@ function listener(event, exec_state, event_data, data) { assertFalse(frame.isConstructCall()); } - if (i > 4) { - assertFalse(frame.isOptimizedFrame()); - assertFalse(frame.isInlinedFrame()); + // When function f is optimized (1 means YES, see runtime.cc) we + // expect an optimized frame for f with g1, g2 and g3 inlined. + if (%GetOptimizationStatus(f) == 1) { + if (i == 1 || i == 2 || i == 3) { + assertTrue(frame.isOptimizedFrame()); + assertTrue(frame.isInlinedFrame()); + assertEquals(4 - i, frame.inlinedFrameIndex()); + } else if (i == 4) { + assertTrue(frame.isOptimizedFrame()); + assertFalse(frame.isInlinedFrame()); + } else { + assertFalse(frame.isOptimizedFrame()); + assertFalse(frame.isInlinedFrame()); + } } } diff --git a/deps/v8/test/mjsunit/debug-function-scopes.js b/deps/v8/test/mjsunit/debug-function-scopes.js deleted file mode 100644 index 4262b950da..0000000000 --- a/deps/v8/test/mjsunit/debug-function-scopes.js +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --expose-debug-as debug - -// Get the Debug object exposed from the debug context global object. -var Debug = debug.Debug; - -function CheckScope(scope_mirror, scope_expectations, expected_scope_type) { - assertEquals(expected_scope_type, scope_mirror.scopeType()); - - var scope_object = scope_mirror.scopeObject().value(); - - for (var name in scope_expectations) { - var actual = scope_object[name]; - var expected = scope_expectations[name]; - assertEquals(expected, actual); - } -} - -// A copy of the scope types from mirror-debugger.js. -var ScopeType = { Global: 0, - Local: 1, - With: 2, - Closure: 3, - Catch: 4, - Block: 5 }; - -var f1 = (function F1(x) { - function F2(y) { - var z = x + y; - with ({w: 5, v: "Capybara"}) { - var F3 = function(a, b) { - function F4(p) { - return p + a + b + z + w + v.length; - } - return F4; - } - return F3(4, 5); - } - } - return F2(17); -})(5); - -var mirror = Debug.MakeMirror(f1); - -assertEquals(5, mirror.scopeCount()); - -CheckScope(mirror.scope(0), { a: 4, b: 5 }, ScopeType.Closure); -CheckScope(mirror.scope(1), { w: 5, v: "Capybara" }, ScopeType.With); -CheckScope(mirror.scope(2), { y: 17, z: 22 }, ScopeType.Closure); -CheckScope(mirror.scope(3), { x: 5 }, ScopeType.Closure); -CheckScope(mirror.scope(4), {}, ScopeType.Global); - -var f2 = function() { return 5; } - -var mirror = Debug.MakeMirror(f2); - -assertEquals(1, mirror.scopeCount()); - -CheckScope(mirror.scope(0), {}, ScopeType.Global); - -var f3 = (function F1(invisible_parameter) { - var invisible1 = 1; - var visible1 = 10; - return (function F2() { - var invisible2 = 2; - return (function F3() { - var visible2 = 20; - var invisible2 = 3; - return (function () {return visible1 + visible2 + visible1a;}); - })(); - })(); -})(5); - -var mirror = Debug.MakeMirror(f3); - -assertEquals(3, mirror.scopeCount()); - -CheckScope(mirror.scope(0), { visible2: 20 }, ScopeType.Closure); -CheckScope(mirror.scope(1), { visible1: 10 }, ScopeType.Closure); -CheckScope(mirror.scope(2), {}, ScopeType.Global); - - -var f4 = (function One() { - try { - throw "I'm error 1"; - } catch (e1) { - try { - throw "I'm error 2"; - } catch (e2) { - return function GetError() { - return e1 + e2; - }; - } - } -})(); - -var mirror = Debug.MakeMirror(f4); - -assertEquals(3, mirror.scopeCount()); - -CheckScope(mirror.scope(0), { e2: "I'm error 2" }, ScopeType.Catch); -CheckScope(mirror.scope(1), { e1: "I'm error 1" }, ScopeType.Catch); -CheckScope(mirror.scope(2), {}, ScopeType.Global); - - -var f5 = (function Raz(p1, p2) { - var p3 = p1 + p2; - return (function() { - var p4 = 20; - var p5 = 21; - var p6 = 22; - return eval("(function(p7){return p1 + p4 + p6 + p7})"); - })(); -})(1,2); - -var mirror = Debug.MakeMirror(f5); - -assertEquals(3, mirror.scopeCount()); - -CheckScope(mirror.scope(0), { p4: 20, p6: 22 }, ScopeType.Closure); -CheckScope(mirror.scope(1), { p1: 1 }, ScopeType.Closure); -CheckScope(mirror.scope(2), {}, ScopeType.Global); - - -function CheckNoScopeVisible(f) { - var mirror = Debug.MakeMirror(f); - assertEquals(0, mirror.scopeCount()); -} - -CheckNoScopeVisible(Number); - -CheckNoScopeVisible(Function.toString); - -// This getter is known to be implemented as closure. -CheckNoScopeVisible(new Error().__lookupGetter__("stack")); - diff --git a/deps/v8/test/mjsunit/debug-scripts-request.js b/deps/v8/test/mjsunit/debug-scripts-request.js index e027563b9b..faa732e141 100644 --- a/deps/v8/test/mjsunit/debug-scripts-request.js +++ b/deps/v8/test/mjsunit/debug-scripts-request.js @@ -78,10 +78,8 @@ function listener(event, exec_state, event_data, data) { var response = safeEval(dcp.processDebugJSONRequest(request)); assertTrue(response.success); - // Test filtering by id. We have to get at least one script back, but - // the exact number depends on the timing of GC. - assertTrue(response.body.length >= 1); - + // Test filtering by id. + assertEquals(2, response.body.length); var script = response.body[0]; var request = '{' + base_request + ',"arguments":{"ids":[' + script.id + ']}}'; diff --git a/deps/v8/test/mjsunit/debug-stepin-builtin-callback.js b/deps/v8/test/mjsunit/debug-stepin-builtin-callback.js deleted file mode 100644 index 223159d4f5..0000000000 --- a/deps/v8/test/mjsunit/debug-stepin-builtin-callback.js +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --expose-debug-as debug - -// Test stepping into callbacks passed to builtin functions. - -Debug = debug.Debug - -var exception = false; - -function array_listener(event, exec_state, event_data, data) { - try { - if (event == Debug.DebugEvent.Break) { - if (breaks == 0) { - exec_state.prepareStep(Debug.StepAction.StepIn, 2); - breaks = 1; - } else if (breaks <= 3) { - breaks++; - // Check whether we break at the expected line. - print(event_data.sourceLineText()); - assertTrue(event_data.sourceLineText().indexOf("Expected to step") > 0); - exec_state.prepareStep(Debug.StepAction.StepIn, 3); - } - } - } catch (e) { - exception = true; - } -}; - -function cb_false(num) { - print("element " + num); // Expected to step to this point. - return false; -} - -function cb_true(num) { - print("element " + num); // Expected to step to this point. - return true; -} - -function cb_reduce(a, b) { - print("elements " + a + " and " + b); // Expected to step to this point. - return a + b; -} - -var a = [1, 2, 3, 4]; - -Debug.setListener(array_listener); - -var breaks = 0; -debugger; -a.forEach(cb_true); -assertFalse(exception); -assertEquals(4, breaks); - -breaks = 0; -debugger; -a.some(cb_false); -assertFalse(exception); -assertEquals(4, breaks); - -breaks = 0; -debugger; -a.every(cb_true); -assertEquals(4, breaks); -assertFalse(exception); - -breaks = 0; -debugger; -a.map(cb_true); -assertFalse(exception); -assertEquals(4, breaks); - -breaks = 0; -debugger; -a.filter(cb_true); -assertFalse(exception); -assertEquals(4, breaks); - -breaks = 0; -debugger; -a.reduce(cb_reduce); -assertFalse(exception); -assertEquals(4, breaks); - -breaks = 0; -debugger; -a.reduceRight(cb_reduce); -assertFalse(exception); -assertEquals(4, breaks); - -Debug.setListener(null); - - -// Test two levels of builtin callbacks: -// Array.forEach calls a callback function, which by itself uses -// Array.forEach with another callback function. - -function second_level_listener(event, exec_state, event_data, data) { - try { - if (event == Debug.DebugEvent.Break) { - if (breaks == 0) { - exec_state.prepareStep(Debug.StepAction.StepIn, 3); - breaks = 1; - } else if (breaks <= 16) { - breaks++; - // Check whether we break at the expected line. - assertTrue(event_data.sourceLineText().indexOf("Expected to step") > 0); - // Step two steps further every four breaks to skip the - // forEach call in the first level of recurision. - var step = (breaks % 4 == 1) ? 6 : 3; - exec_state.prepareStep(Debug.StepAction.StepIn, step); - } - } - } catch (e) { - exception = true; - } -}; - -function cb_foreach(num) { - a.forEach(cb_true); - print("back to the first level of recursion."); -} - -Debug.setListener(second_level_listener); - -breaks = 0; -debugger; -a.forEach(cb_foreach); -assertFalse(exception); -assertEquals(17, breaks); - -Debug.setListener(null); diff --git a/deps/v8/test/mjsunit/declare-locally.js b/deps/v8/test/mjsunit/declare-locally.js index 20bfe6da1f..93fcb85f3c 100644 --- a/deps/v8/test/mjsunit/declare-locally.js +++ b/deps/v8/test/mjsunit/declare-locally.js @@ -33,13 +33,11 @@ // This exercises the code in runtime.cc in // DeclareGlobal...Locally(). -// Flags: --es52_globals - this.__proto__.foo = 42; this.__proto__.bar = 87; -eval("assertEquals(undefined, foo); var foo = 87;"); +eval("assertEquals(42, foo); var foo = 87;"); assertEquals(87, foo); -eval("assertEquals(undefined, bar); const bar = 42;"); +eval("assertEquals(87, bar); const bar = 42;"); assertEquals(42, bar); diff --git a/deps/v8/test/mjsunit/harmony/debug-function-scopes.js b/deps/v8/test/mjsunit/harmony/debug-function-scopes.js deleted file mode 100644 index 0113be672b..0000000000 --- a/deps/v8/test/mjsunit/harmony/debug-function-scopes.js +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --expose-debug-as debug --harmony-scoping - -"use strict"; - -// Get the Debug object exposed from the debug context global object. -var Debug = debug.Debug; - -function CheckScope(scope_mirror, scope_expectations, expected_scope_type) { - assertEquals(expected_scope_type, scope_mirror.scopeType()); - - var scope_object = scope_mirror.scopeObject().value(); - - for (let name in scope_expectations) { - let actual = scope_object[name]; - let expected = scope_expectations[name]; - assertEquals(expected, actual); - } -} - -// A copy of the scope types from mirror-debugger.js. -var ScopeType = { Global: 0, - Local: 1, - With: 2, - Closure: 3, - Catch: 4, - Block: 5 }; - -var f1 = (function F1(x) { - function F2(y) { - var z = x + y; - { - var w = 5; - var v = "Capybara"; - var F3 = function(a, b) { - function F4(p) { - return p + a + b + z + w + v.length; - } - return F4; - } - return F3(4, 5); - } - } - return F2(17); -})(5); - -var mirror = Debug.MakeMirror(f1); - -assertEquals(4, mirror.scopeCount()); - -CheckScope(mirror.scope(0), { a: 4, b: 5 }, ScopeType.Closure); -CheckScope(mirror.scope(1), { z: 22, w: 5, v: "Capybara" }, ScopeType.Closure); -CheckScope(mirror.scope(2), { x: 5 }, ScopeType.Closure); -CheckScope(mirror.scope(3), {}, ScopeType.Global); - -var f2 = (function() { - var v1 = 3; - var v2 = 4; - let l0 = 0; - { - var v3 = 5; - let l1 = 6; - let l2 = 7; - { - var v4 = 8; - let l3 = 9; - { - var v5 = "Cat"; - let l4 = 11; - var v6 = l4; - return function() { - return l0 + v1 + v3 + l2 + l3 + v6; - }; - } - } - } -})(); - -var mirror = Debug.MakeMirror(f2); - -assertEquals(5, mirror.scopeCount()); - -// Implementation artifact: l4 isn't used in closure, but still it is saved. -CheckScope(mirror.scope(0), { l4: 11 }, ScopeType.Block); - -CheckScope(mirror.scope(1), { l3: 9 }, ScopeType.Block); -CheckScope(mirror.scope(2), { l1: 6, l2: 7 }, ScopeType.Block); -CheckScope(mirror.scope(3), { v1:3, l0: 0, v3: 5, v6: 11 }, ScopeType.Closure); -CheckScope(mirror.scope(4), {}, ScopeType.Global); diff --git a/deps/v8/test/mjsunit/harmony/module-linking.js b/deps/v8/test/mjsunit/harmony/module-linking.js deleted file mode 100644 index 13ca6f782f..0000000000 --- a/deps/v8/test/mjsunit/harmony/module-linking.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --harmony-modules --harmony-scoping - -// Test basic module linking. - -"use strict"; - -let log = ""; - -export let x = (log += "1"); - -export module B = A.B - -export module A { - export let x = (log += "2"); - let y = (log += "3"); - export function f() { log += "5" }; - export module B { - module BB = B; - export BB, x; - let x = (log += "4"); - f(); - let y = (log += "6"); - } - export let z = (log += "7"); - export module C { - export let z = (log += "8"); - export module D = B - export module C = A.C - } - module D {} -} - -export module M1 { - export module A2 = M2; - export let x = (log += "9"); -} -export module M2 { - export module A1 = M1; - export let x = (log += "0"); -} - -assertEquals("object", typeof A); -assertTrue('x' in A); -assertFalse('y' in A); -assertTrue('f' in A); -assertTrue('B' in A); -assertTrue('z' in A); -assertTrue('C' in A); -assertFalse('D' in A); - -assertEquals("object", typeof B); -assertTrue('BB' in B); -assertTrue('x' in B); -assertFalse('y' in B); - -assertEquals("object", typeof A.B); -assertTrue('BB' in A.B); -assertTrue('x' in A.B); -assertFalse('y' in A.B); - -assertEquals("object", typeof A.B.BB); -assertTrue('BB' in A.B.BB); -assertTrue('x' in A.B.BB); -assertFalse('y' in A.B.BB); - -assertEquals("object", typeof A.C); -assertTrue('z' in A.C); -assertTrue('D' in A.C); -assertTrue('C' in A.C); - -assertEquals("object", typeof M1); -assertEquals("object", typeof M2); -assertTrue('A2' in M1); -assertTrue('A1' in M2); -assertEquals("object", typeof M1.A2); -assertEquals("object", typeof M2.A1); -assertTrue('A1' in M1.A2); -assertTrue('A2' in M2.A1); -assertEquals("object", typeof M1.A2.A1); -assertEquals("object", typeof M2.A1.A2); - -assertSame(B, A.B); -assertSame(B, B.BB); -assertSame(B, A.C.D); -assertSame(A.C, A.C.C); -assertFalse(A.D === A.C.D); - -assertSame(M1, M2.A1); -assertSame(M2, M1.A2); -assertSame(M1, M1.A2.A1); -assertSame(M2, M2.A1.A2); - -// TODO(rossberg): inner declarations are not executed yet. -// assertEquals("1234567890", log); diff --git a/deps/v8/test/mjsunit/harmony/module-parsing.js b/deps/v8/test/mjsunit/harmony/module-parsing.js index cdd0a2e00d..93e69e3ad9 100644 --- a/deps/v8/test/mjsunit/harmony/module-parsing.js +++ b/deps/v8/test/mjsunit/harmony/module-parsing.js @@ -70,7 +70,7 @@ module B { import i0 from I import i1, i2, i3, M from I - //import i4, i5 from "http://where" + import i4, i5 from "http://where" } module I { @@ -85,7 +85,7 @@ module D3 = D2 module E1 at "http://where" module E2 at "http://where"; -module E3 = E1 +module E3 = E1.F // Check that ASI does not interfere. @@ -103,11 +103,11 @@ at "file://local" import -vx +x , -vy +y from -B +"file://local" module Wrap { diff --git a/deps/v8/test/mjsunit/harmony/module-resolution.js b/deps/v8/test/mjsunit/harmony/module-resolution.js index a1b991749c..f9f492cffc 100644 --- a/deps/v8/test/mjsunit/harmony/module-resolution.js +++ b/deps/v8/test/mjsunit/harmony/module-resolution.js @@ -129,7 +129,7 @@ export module M2 { export module External at "external.js" export module External1 = External -//export module ExternalA = External.A +export module ExternalA = External.A export module InnerExternal { export module E at "external.js" } diff --git a/deps/v8/test/mjsunit/math-floor-of-div.js b/deps/v8/test/mjsunit/math-floor-of-div.js deleted file mode 100644 index e917182c71..0000000000 --- a/deps/v8/test/mjsunit/math-floor-of-div.js +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --nouse_inlining - -// Use this function as reference. Make sure it is not inlined. -function div(a, b) { - return a / b; -} - -var limit = 0x1000000; -var exhaustive_limit = 100; -var step = 10; -var values = [0x10000001, - 0x12345678, - -0x789abcdf, // 0x87654321 - 0x01234567, - 0x76543210, - -0x80000000, // 0x80000000 - 0x7fffffff, - -0x0fffffff, // 0xf0000001 - 0x00000010, - -0x01000000 // 0xff000000 - ]; - -function test_div() { - var c = 0; - for (var k = 0; k <= limit; k++) { - if (k > exhaustive_limit) { c += step; k += c; } - assertEquals(Math.floor(div(k, 1)), Math.floor(k / 1)); - assertEquals(Math.floor(div(k, -1)), Math.floor(k / -1)); - assertEquals(Math.floor(div(k, 2)), Math.floor(k / 2)); - assertEquals(Math.floor(div(k, -2)), Math.floor(k / -2)); - assertEquals(Math.floor(div(k, 3)), Math.floor(k / 3)); - assertEquals(Math.floor(div(k, -3)), Math.floor(k / -3)); - assertEquals(Math.floor(div(k, 4)), Math.floor(k / 4)); - assertEquals(Math.floor(div(k, -4)), Math.floor(k / -4)); - assertEquals(Math.floor(div(k, 5)), Math.floor(k / 5)); - assertEquals(Math.floor(div(k, -5)), Math.floor(k / -5)); - assertEquals(Math.floor(div(k, 6)), Math.floor(k / 6)); - assertEquals(Math.floor(div(k, -6)), Math.floor(k / -6)); - assertEquals(Math.floor(div(k, 7)), Math.floor(k / 7)); - assertEquals(Math.floor(div(k, -7)), Math.floor(k / -7)); - assertEquals(Math.floor(div(k, 8)), Math.floor(k / 8)); - assertEquals(Math.floor(div(k, -8)), Math.floor(k / -8)); - assertEquals(Math.floor(div(k, 9)), Math.floor(k / 9)); - assertEquals(Math.floor(div(k, -9)), Math.floor(k / -9)); - assertEquals(Math.floor(div(k, 10)), Math.floor(k / 10)); - assertEquals(Math.floor(div(k, -10)), Math.floor(k / -10)); - assertEquals(Math.floor(div(k, 11)), Math.floor(k / 11)); - assertEquals(Math.floor(div(k, -11)), Math.floor(k / -11)); - assertEquals(Math.floor(div(k, 12)), Math.floor(k / 12)); - assertEquals(Math.floor(div(k, -12)), Math.floor(k / -12)); - assertEquals(Math.floor(div(k, 13)), Math.floor(k / 13)); - assertEquals(Math.floor(div(k, -13)), Math.floor(k / -13)); - assertEquals(Math.floor(div(k, 14)), Math.floor(k / 14)); - assertEquals(Math.floor(div(k, -14)), Math.floor(k / -14)); - assertEquals(Math.floor(div(k, 15)), Math.floor(k / 15)); - assertEquals(Math.floor(div(k, -15)), Math.floor(k / -15)); - assertEquals(Math.floor(div(k, 16)), Math.floor(k / 16)); - assertEquals(Math.floor(div(k, -16)), Math.floor(k / -16)); - assertEquals(Math.floor(div(k, 17)), Math.floor(k / 17)); - assertEquals(Math.floor(div(k, -17)), Math.floor(k / -17)); - assertEquals(Math.floor(div(k, 18)), Math.floor(k / 18)); - assertEquals(Math.floor(div(k, -18)), Math.floor(k / -18)); - assertEquals(Math.floor(div(k, 19)), Math.floor(k / 19)); - assertEquals(Math.floor(div(k, -19)), Math.floor(k / -19)); - assertEquals(Math.floor(div(k, 20)), Math.floor(k / 20)); - assertEquals(Math.floor(div(k, -20)), Math.floor(k / -20)); - assertEquals(Math.floor(div(k, 21)), Math.floor(k / 21)); - assertEquals(Math.floor(div(k, -21)), Math.floor(k / -21)); - assertEquals(Math.floor(div(k, 22)), Math.floor(k / 22)); - assertEquals(Math.floor(div(k, -22)), Math.floor(k / -22)); - assertEquals(Math.floor(div(k, 23)), Math.floor(k / 23)); - assertEquals(Math.floor(div(k, -23)), Math.floor(k / -23)); - assertEquals(Math.floor(div(k, 24)), Math.floor(k / 24)); - assertEquals(Math.floor(div(k, -24)), Math.floor(k / -24)); - assertEquals(Math.floor(div(k, 25)), Math.floor(k / 25)); - assertEquals(Math.floor(div(k, -25)), Math.floor(k / -25)); - assertEquals(Math.floor(div(k, 125)), Math.floor(k / 125)); - assertEquals(Math.floor(div(k, -125)), Math.floor(k / -125)); - assertEquals(Math.floor(div(k, 625)), Math.floor(k / 625)); - assertEquals(Math.floor(div(k, -625)), Math.floor(k / -625)); - } - c = 0; - for (var k = 0; k <= limit; k++) { - if (k > exhaustive_limit) { c += step; k += c; } - assertEquals(Math.floor(div(-k, 1)), Math.floor(-k / 1)); - assertEquals(Math.floor(div(-k, -1)), Math.floor(-k / -1)); - assertEquals(Math.floor(div(-k, 2)), Math.floor(-k / 2)); - assertEquals(Math.floor(div(-k, -2)), Math.floor(-k / -2)); - assertEquals(Math.floor(div(-k, 3)), Math.floor(-k / 3)); - assertEquals(Math.floor(div(-k, -3)), Math.floor(-k / -3)); - assertEquals(Math.floor(div(-k, 4)), Math.floor(-k / 4)); - assertEquals(Math.floor(div(-k, -4)), Math.floor(-k / -4)); - assertEquals(Math.floor(div(-k, 5)), Math.floor(-k / 5)); - assertEquals(Math.floor(div(-k, -5)), Math.floor(-k / -5)); - assertEquals(Math.floor(div(-k, 6)), Math.floor(-k / 6)); - assertEquals(Math.floor(div(-k, -6)), Math.floor(-k / -6)); - assertEquals(Math.floor(div(-k, 7)), Math.floor(-k / 7)); - assertEquals(Math.floor(div(-k, -7)), Math.floor(-k / -7)); - assertEquals(Math.floor(div(-k, 8)), Math.floor(-k / 8)); - assertEquals(Math.floor(div(-k, -8)), Math.floor(-k / -8)); - assertEquals(Math.floor(div(-k, 9)), Math.floor(-k / 9)); - assertEquals(Math.floor(div(-k, -9)), Math.floor(-k / -9)); - assertEquals(Math.floor(div(-k, 10)), Math.floor(-k / 10)); - assertEquals(Math.floor(div(-k, -10)), Math.floor(-k / -10)); - assertEquals(Math.floor(div(-k, 11)), Math.floor(-k / 11)); - assertEquals(Math.floor(div(-k, -11)), Math.floor(-k / -11)); - assertEquals(Math.floor(div(-k, 12)), Math.floor(-k / 12)); - assertEquals(Math.floor(div(-k, -12)), Math.floor(-k / -12)); - assertEquals(Math.floor(div(-k, 13)), Math.floor(-k / 13)); - assertEquals(Math.floor(div(-k, -13)), Math.floor(-k / -13)); - assertEquals(Math.floor(div(-k, 14)), Math.floor(-k / 14)); - assertEquals(Math.floor(div(-k, -14)), Math.floor(-k / -14)); - assertEquals(Math.floor(div(-k, 15)), Math.floor(-k / 15)); - assertEquals(Math.floor(div(-k, -15)), Math.floor(-k / -15)); - assertEquals(Math.floor(div(-k, 16)), Math.floor(-k / 16)); - assertEquals(Math.floor(div(-k, -16)), Math.floor(-k / -16)); - assertEquals(Math.floor(div(-k, 17)), Math.floor(-k / 17)); - assertEquals(Math.floor(div(-k, -17)), Math.floor(-k / -17)); - assertEquals(Math.floor(div(-k, 18)), Math.floor(-k / 18)); - assertEquals(Math.floor(div(-k, -18)), Math.floor(-k / -18)); - assertEquals(Math.floor(div(-k, 19)), Math.floor(-k / 19)); - assertEquals(Math.floor(div(-k, -19)), Math.floor(-k / -19)); - assertEquals(Math.floor(div(-k, 20)), Math.floor(-k / 20)); - assertEquals(Math.floor(div(-k, -20)), Math.floor(-k / -20)); - assertEquals(Math.floor(div(-k, 21)), Math.floor(-k / 21)); - assertEquals(Math.floor(div(-k, -21)), Math.floor(-k / -21)); - assertEquals(Math.floor(div(-k, 22)), Math.floor(-k / 22)); - assertEquals(Math.floor(div(-k, -22)), Math.floor(-k / -22)); - assertEquals(Math.floor(div(-k, 23)), Math.floor(-k / 23)); - assertEquals(Math.floor(div(-k, -23)), Math.floor(-k / -23)); - assertEquals(Math.floor(div(-k, 24)), Math.floor(-k / 24)); - assertEquals(Math.floor(div(-k, -24)), Math.floor(-k / -24)); - assertEquals(Math.floor(div(-k, 25)), Math.floor(-k / 25)); - assertEquals(Math.floor(div(-k, -25)), Math.floor(-k / -25)); - assertEquals(Math.floor(div(-k, 125)), Math.floor(-k / 125)); - assertEquals(Math.floor(div(-k, -125)), Math.floor(-k / -125)); - assertEquals(Math.floor(div(-k, 625)), Math.floor(-k / 625)); - assertEquals(Math.floor(div(-k, -625)), Math.floor(-k / -625)); - } - // Test for edge cases. - // Use (values[key] | 0) to force the integer type. - for (var i = 0; i < values.length; i++) { - for (var j = 0; j < values.length; j++) { - assertEquals(Math.floor(div((values[i] | 0), (values[j] | 0))), - Math.floor((values[i] | 0) / (values[j] | 0))); - assertEquals(Math.floor(div(-(values[i] | 0), (values[j] | 0))), - Math.floor(-(values[i] | 0) / (values[j] | 0))); - assertEquals(Math.floor(div((values[i] | 0), -(values[j] | 0))), - Math.floor((values[i] | 0) / -(values[j] | 0))); - assertEquals(Math.floor(div(-(values[i] | 0), -(values[j] | 0))), - Math.floor(-(values[i] | 0) / -(values[j] | 0))); - } - } -} - -test_div(); -%OptimizeFunctionOnNextCall(test_div); -test_div(); - -// Test for negative zero and overflow. -// Separate the tests to prevent deoptimizations from making the other optimized -// test unreachable. - -function IsNegativeZero(x) { - assertTrue(x == 0); // Is 0 or -0. - var y = 1 / x; - assertFalse(isFinite(y)); - return y < 0; -} - -function test_div_deopt_minus_zero() { - var zero_in_array = [0]; - assertTrue(IsNegativeZero(Math.floor((zero_in_array[0] | 0) / -1))); -} - -function test_div_deopt_overflow() { - // We box the value in an array to avoid constant propagation. - var min_int_in_array = [-2147483648]; - // We use '| 0' to force the representation to int32. - assertEquals(-min_int_in_array[0], - Math.floor((min_int_in_array[0] | 0) / -1)); -} - -test_div_deopt_minus_zero(); -test_div_deopt_overflow(); -%OptimizeFunctionOnNextCall(test_div_deopt_minus_zero); -%OptimizeFunctionOnNextCall(test_div_deopt_overflow); -test_div_deopt_minus_zero(); -test_div_deopt_overflow(); diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js index 65fb301b44..033c78f4b0 100644 --- a/deps/v8/test/mjsunit/mjsunit.js +++ b/deps/v8/test/mjsunit/mjsunit.js @@ -75,7 +75,7 @@ var assertTrue; // Checks that the found value is false. var assertFalse; -// Checks that the found value is null. Kept for historical compatibility, +// Checks that the found value is null. Kept for historical compatability, // please just use assertEquals(null, expected). var assertNull; diff --git a/deps/v8/test/mjsunit/regexp-capture-3.js b/deps/v8/test/mjsunit/regexp-capture-3.js index b676f01c2c..50e423ff30 100644 --- a/deps/v8/test/mjsunit/regexp-capture-3.js +++ b/deps/v8/test/mjsunit/regexp-capture-3.js @@ -25,195 +25,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -function oneMatch(re) { - "abcd".replace(re, function() { }); - assertEquals("abcd", RegExp.input); - assertEquals("a", RegExp.leftContext); - assertEquals("b", RegExp.lastMatch); - assertEquals("", RegExp.lastParen); - assertEquals(undefined, RegExp.lastIndex); - assertEquals(undefined, RegExp.index); - assertEquals("cd", RegExp.rightContext); - for (var i = 1; i < 10; i++) { - assertEquals("", RegExp['$' + i]); - } -} +"abcd".replace(/b/g, function() { }); -oneMatch(/b/); -oneMatch(/b/g); - -"abcdabcd".replace(/b/g, function() { }); -assertEquals("abcdabcd", RegExp.input); -assertEquals("abcda", RegExp.leftContext); -assertEquals("b", RegExp.lastMatch); -assertEquals("", RegExp.lastParen); -assertEquals(undefined, RegExp.lastIndex); -assertEquals(undefined, RegExp.index); assertEquals("cd", RegExp.rightContext); -for (var i = 1; i < 10; i++) { - assertEquals("", RegExp['$' + i]); -} - -function captureMatch(re) { - "abcd".replace(re, function() { }); - assertEquals("abcd", RegExp.input); - assertEquals("a", RegExp.leftContext); - assertEquals("bc", RegExp.lastMatch); - assertEquals("c", RegExp.lastParen); - assertEquals(undefined, RegExp.lastIndex); - assertEquals(undefined, RegExp.index); - assertEquals("d", RegExp.rightContext); - assertEquals('b', RegExp.$1); - assertEquals('c', RegExp.$2); - for (var i = 3; i < 10; i++) { - assertEquals("", RegExp['$' + i]); - } -} - -captureMatch(/(b)(c)/); -captureMatch(/(b)(c)/g); - -"abcdabcd".replace(/(b)(c)/g, function() { }); -assertEquals("abcdabcd", RegExp.input); -assertEquals("abcda", RegExp.leftContext); -assertEquals("bc", RegExp.lastMatch); -assertEquals("c", RegExp.lastParen); -assertEquals(undefined, RegExp.lastIndex); -assertEquals(undefined, RegExp.index); -assertEquals("d", RegExp.rightContext); -assertEquals('b', RegExp.$1); -assertEquals('c', RegExp.$2); -for (var i = 3; i < 10; i++) { - assertEquals("", RegExp['$' + i]); -} - - -function Override() { - // Set the internal lastMatchInfoOverride. After calling this we do a normal - // match and verify the override was cleared and that we record the new - // captures. - "abcdabcd".replace(/(b)(c)/g, function() { }); -} - - -function TestOverride(input, expect, property, re_src) { - var re = new RegExp(re_src); - var re_g = new RegExp(re_src, "g"); - - function OverrideCase(fn) { - Override(); - fn(); - assertEquals(expect, RegExp[property]); - } - - OverrideCase(function() { return input.replace(re, "x"); }); - OverrideCase(function() { return input.replace(re_g, "x"); }); - OverrideCase(function() { return input.replace(re, ""); }); - OverrideCase(function() { return input.replace(re_g, ""); }); - OverrideCase(function() { return input.match(re); }); - OverrideCase(function() { return input.match(re_g); }); - OverrideCase(function() { return re.test(input); }); - OverrideCase(function() { return re_g.test(input); }); -} - -var input = "bar.foo baz......"; -var re_str = "(ba.).*?f"; -TestOverride(input, "bar", "$1", re_str); - -input = "foo bar baz"; -var re_str = "bar"; -TestOverride(input, "bar", "$&", re_str); - - -function no_last_match(fn) { - fn(); - assertEquals("hestfisk", RegExp.$1); -} - -/(hestfisk)/.test("There's no such thing as a hestfisk!"); - -no_last_match(function() { "foo".replace("f", ""); }); -no_last_match(function() { "foo".replace("f", "f"); }); -no_last_match(function() { "foo".split("o"); }); - -var base = "In the music. In the music. "; -var cons = base + base + base + base; -no_last_match(function() { cons.replace("x", "y"); }); -no_last_match(function() { cons.replace("e", "E"); }); - - -// Here's one that matches once, then tries to match again, but fails. -// Verify that the last match info is from the last match, not from the -// failure that came after. -"bar.foo baz......".replace(/(ba.).*?f/g, function() { return "x";}); -assertEquals("bar", RegExp.$1); - - -// A test that initially does a zero width match, but later does a non-zero -// width match. -var a = "foo bar baz".replace(/^|bar/g, ""); -assertEquals("foo baz", a); - -a = "foo bar baz".replace(/^|bar/g, "*"); -assertEquals("*foo * baz", a); - -// We test FilterASCII using regexps that will backtrack forever. Since -// a regexp with a non-ASCII character in it can never match an ASCII -// string we can test that the relevant node is removed by verifying that -// there is no hang. -function NoHang(re) { - "This is an ASCII string that could take forever".match(re); -} - - -NoHang(/(((.*)*)*x)å/); // Continuation after loop is filtered, so is loop. -NoHang(/(((.*)*)*å)foo/); // Body of loop filtered. -NoHang(/å(((.*)*)*x)/); // Everything after a filtered character is filtered. -NoHang(/(((.*)*)*x)å/); // Everything before a filtered character is filtered. -NoHang(/[æøå](((.*)*)*x)/); // Everything after a filtered class is filtered. -NoHang(/(((.*)*)*x)[æøå]/); // Everything before a filtered class is filtered. -NoHang(/[^\x00-\x7f](((.*)*)*x)/); // After negated class. -NoHang(/(((.*)*)*x)[^\x00-\x7f]/); // Before negated class. -NoHang(/(?!(((.*)*)*x)å)foo/); // Negative lookahead is filtered. -NoHang(/(?!(((.*)*)*x))å/); // Continuation branch of negative lookahead. -NoHang(/(?=(((.*)*)*x)å)foo/); // Positive lookahead is filtered. -NoHang(/(?=(((.*)*)*x))å/); // Continuation branch of positive lookahead. -NoHang(/(?=å)(((.*)*)*x)/); // Positive lookahead also prunes continuation. -NoHang(/(æ|ø|å)(((.*)*)*x)/); // All branches of alternation are filtered. -NoHang(/(a|b|(((.*)*)*x))å/); // 1 out of 3 branches pruned. -NoHang(/(a|(((.*)*)*x)ø|(((.*)*)*x)å)/); // 2 out of 3 branches pruned. - -var s = "Don't prune based on a repetition of length 0"; -assertEquals(null, s.match(/å{1,1}prune/)); -assertEquals("prune", (s.match(/å{0,0}prune/)[0])); - -// Some very deep regexps where FilterASCII gives up in order not to make the -// stack overflow. -var regex6 = /a*\u0100*\w/; -var input0 = "a"; -regex6.exec(input0); - -var re = "\u0100*\\w"; - -for (var i = 0; i < 200; i++) re = "a*" + re; - -var regex7 = new RegExp(re); -regex7.exec(input0); - -var regex8 = new RegExp(re, "i"); -regex8.exec(input0); - -re = "[\u0100]*\\w"; -for (var i = 0; i < 200; i++) re = "a*" + re; - -var regex9 = new RegExp(re); -regex9.exec(input0); - -var regex10 = new RegExp(re, "i"); -regex10.exec(input0); - -var regex11 = /^(?:[^\u0000-\u0080]|[0-9a-z?,.!&\s#()])+$/i; -regex11.exec(input0); - -var regex12 = /u(\xf0{8}?\D*?|( ? !)$h??(|)*?(||)+?\6((?:\W\B|--\d-*-|)?$){0, }?|^Y( ? !1)\d+)+a/; -regex12.exec(""); diff --git a/deps/v8/test/mjsunit/regexp-capture.js b/deps/v8/test/mjsunit/regexp-capture.js index 307309482a..8aae71795a 100755 --- a/deps/v8/test/mjsunit/regexp-capture.js +++ b/deps/v8/test/mjsunit/regexp-capture.js @@ -56,5 +56,3 @@ assertEquals(["bbc", "b"], /^(b+|a){1,2}?bc/.exec("bbc")); assertEquals(["bbaa", "a", "", "a"], /((\3|b)\2(a)){2,}/.exec("bbaababbabaaaaabbaaaabba")); -// From crbug.com/128821 - don't hang: -"".match(/((a|i|A|I|u|o|U|O)(s|c|b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|w|x|y|z|B|C|D|F|G|H|J|K|L|M|N|P|Q|R|S|T|V|W|X|Y|Z)*) de\/da([.,!?\s]|$)/); diff --git a/deps/v8/test/mjsunit/regress/regress-1119.js b/deps/v8/test/mjsunit/regress/regress-1119.js index 5fd8f369b1..16b2e4f935 100644 --- a/deps/v8/test/mjsunit/regress/regress-1119.js +++ b/deps/v8/test/mjsunit/regress/regress-1119.js @@ -28,19 +28,17 @@ // Test runtime declaration of properties with var which are intercepted // by JS accessors. -// Flags: --es52_globals - -this.__defineSetter__("x", function() { hasBeenInvoked = true; }); -this.__defineSetter__("y", function() { throw 'exception'; }); +__proto__.__defineSetter__("x", function() { hasBeenInvoked = true; }); +__proto__.__defineSetter__("y", function() { throw 'exception'; }); var hasBeenInvoked = false; eval("try { } catch (e) { var x = false; }"); assertTrue(hasBeenInvoked); -// This has to run in global scope, so cannot use assertThrows... +var exception; try { eval("try { } catch (e) { var y = false; }"); - assertUnreachable(); } catch (e) { - assertEquals('exception', e); + exception = e; } +assertEquals('exception', exception); diff --git a/deps/v8/test/mjsunit/regress/regress-115452.js b/deps/v8/test/mjsunit/regress/regress-115452.js index dc711581e9..7e424ed88b 100644 --- a/deps/v8/test/mjsunit/regress/regress-115452.js +++ b/deps/v8/test/mjsunit/regress/regress-115452.js @@ -27,21 +27,22 @@ // Test that a function declaration cannot overwrite a read-only property. -// Flags: --es52_globals - +print(0) function foobl() {} assertTrue(typeof this.foobl == "function"); assertTrue(Object.getOwnPropertyDescriptor(this, "foobl").writable); +print(1) Object.defineProperty(this, "foobl", {value: 1, writable: false}); assertSame(1, this.foobl); assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable); -// This has to run in global scope, so cannot use assertThrows... -try { - eval("function foobl() {}"); // Should throw. - assertUnreachable(); -} catch (e) { - assertInstanceof(e, TypeError); -} +print(2) +eval("function foobl() {}"); assertSame(1, this.foobl); +assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable); + +print(3) +eval("function foobl() {}"); +assertSame(1, this.foobl); +assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable); diff --git a/deps/v8/test/mjsunit/regress/regress-1170.js b/deps/v8/test/mjsunit/regress/regress-1170.js index 8c5f6f8ab4..66ed9f29e2 100644 --- a/deps/v8/test/mjsunit/regress/regress-1170.js +++ b/deps/v8/test/mjsunit/regress/regress-1170.js @@ -25,74 +25,48 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --es52_globals - var setter_value = 0; -this.__defineSetter__("a", function(v) { setter_value = v; }); +__proto__.__defineSetter__("a", function(v) { setter_value = v; }); eval("var a = 1"); assertEquals(1, setter_value); -assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a")); +assertFalse(this.hasOwnProperty("a")); eval("with({}) { eval('var a = 2') }"); assertEquals(2, setter_value); -assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a")); +assertFalse(this.hasOwnProperty("a")); // Function declarations are treated specially to match Safari. We do // not call setters for them. -this.__defineSetter__("a", function(v) { assertUnreachable(); }); eval("function a() {}"); -assertTrue("value" in Object.getOwnPropertyDescriptor(this, "a")); +assertTrue(this.hasOwnProperty("a")); -this.__defineSetter__("b", function(v) { setter_value = v; }); +__proto__.__defineSetter__("b", function(v) { assertUnreachable(); }); +var exception = false; try { - eval("const b = 3"); + eval("const b = 23"); } catch(e) { - assertUnreachable(); + exception = true; + assertTrue(/TypeError/.test(e)); } -assertEquals(3, setter_value); +assertFalse(exception); +exception = false; try { eval("with({}) { eval('const b = 23') }"); } catch(e) { - assertInstanceof(e, TypeError); + exception = true; + assertTrue(/TypeError/.test(e)); } +assertTrue(exception); -this.__defineSetter__("c", function(v) { throw 42; }); +__proto__.__defineSetter__("c", function(v) { throw 42; }); +exception = false; try { eval("var c = 1"); - assertUnreachable(); } catch(e) { + exception = true; assertEquals(42, e); - assertFalse("value" in Object.getOwnPropertyDescriptor(this, "c")); -} - - - - -__proto__.__defineSetter__("aa", function(v) { assertUnreachable(); }); -eval("var aa = 1"); -assertTrue(this.hasOwnProperty("aa")); - -__proto__.__defineSetter__("bb", function(v) { assertUnreachable(); }); -eval("with({}) { eval('var bb = 2') }"); -assertTrue(this.hasOwnProperty("bb")); - -// Function declarations are treated specially to match Safari. We do -// not call setters for them. -__proto__.__defineSetter__("cc", function(v) { assertUnreachable(); }); -eval("function cc() {}"); -assertTrue(this.hasOwnProperty("cc")); - -__proto__.__defineSetter__("dd", function(v) { assertUnreachable(); }); -try { - eval("const dd = 23"); -} catch(e) { - assertUnreachable(); -} - -try { - eval("with({}) { eval('const dd = 23') }"); -} catch(e) { - assertInstanceof(e, TypeError); + assertFalse(this.hasOwnProperty("c")); } +assertTrue(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-119609.js b/deps/v8/test/mjsunit/regress/regress-119609.js deleted file mode 100644 index 99041adaf4..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-119609.js +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --expose-debug-as debug - -Debug = debug.Debug; - -var exception = false; - -function listener(event, exec_state, event_data, data) { - try { - if (event == Debug.DebugEvent.Break) { - function lookup(name) { - return exec_state.frame(0).evaluate(name).value(); - } - - assertEquals(3, lookup("e")); - assertEquals(4, lookup("f")); - assertEquals(1, lookup("a")); - - try { - assertEquals(2, lookup("b")); - } catch (e) { - assertEquals("ReferenceError: b is not defined", e.toString()); - } - } - } catch (e) { - exception = e.toString() + e.stack; - } -} - -Debug.setListener(listener); - -function f(a, b) { - var c = 3; - function d(e, f) { - var g = a; - var h = c; - debugger; - } - - return d; -} - -f(1, 2)(3, 4); - -assertFalse(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-120099.js b/deps/v8/test/mjsunit/regress/regress-120099.js deleted file mode 100644 index 3b06f4da2c..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-120099.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -'use strict'; - -var a = Object.create(Object.prototype); -var b = Object.create(Object.prototype); -assertFalse(a === b); - -Object.defineProperty(a, 'x', { value: 1 }); -assertTrue(a.x === 1); -assertTrue(b.x === undefined); - -b.x = 2; -assertTrue(a.x === 1); -assertTrue(b.x === 2); diff --git a/deps/v8/test/mjsunit/regress/regress-1217.js b/deps/v8/test/mjsunit/regress/regress-1217.js index e00d5371ad..6530549864 100644 --- a/deps/v8/test/mjsunit/regress/regress-1217.js +++ b/deps/v8/test/mjsunit/regress/regress-1217.js @@ -30,7 +30,7 @@ var proto = RegExp.prototype; assertEquals("[object RegExp]", Object.prototype.toString.call(proto)); -assertEquals("(?:)", proto.source); +assertEquals("", proto.source); assertEquals(false, proto.global); assertEquals(false, proto.multiline); assertEquals(false, proto.ignoreCase); diff --git a/deps/v8/test/mjsunit/regress/regress-123512.js b/deps/v8/test/mjsunit/regress/regress-123512.js deleted file mode 100644 index 8a747bc5f7..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-123512.js +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax - -// Test that boilerplate objects for array literals with non-constant -// elements (which will contain the hole at non-constant positions) will -// not cause prototype chain lookups when generating optimized code. - -function f(x) { - return [x][0]; -} - -// Test data element on prototype. -Object.prototype[0] = 23; -assertSame(1, f(1)); -assertSame(2, f(2)); -%OptimizeFunctionOnNextCall(f); -assertSame(3, f(3)); -%DeoptimizeFunction(f); - -// Test accessor element on prototype. -Object.prototype.__defineGetter__(0, function() { throw Error(); }); -assertSame(4, f(4)); -assertSame(5, f(5)); -%OptimizeFunctionOnNextCall(f); -assertSame(6, f(6)); -%DeoptimizeFunction(f); - -// Test the same on boilerplate objects for object literals that contain -// both non-constant properties and non-constant elements. - -function g(x, y) { - var o = { foo:x, 0:y }; - return o.foo + o[0]; -} - -// Test data property and element on prototype. -Object.prototype[0] = 23; -Object.prototype.foo = 42; -assertSame(3, g(1, 2)); -assertSame(5, g(2, 3)); -%OptimizeFunctionOnNextCall(g); -assertSame(7, g(3, 4)); -%DeoptimizeFunction(g); - -// Test accessor property and element on prototype. -Object.prototype.__defineGetter__(0, function() { throw Error(); }); -Object.prototype.__defineGetter__('foo', function() { throw Error(); }); -assertSame(3, g(1, 2)); -assertSame(5, g(2, 3)); -%OptimizeFunctionOnNextCall(g); -assertSame(7, g(3, 4)); -%DeoptimizeFunction(g); diff --git a/deps/v8/test/mjsunit/regress/regress-123919.js b/deps/v8/test/mjsunit/regress/regress-123919.js deleted file mode 100644 index be3460815b..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-123919.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --gc-global - -function g(max,val) { - this.x = 0; - for (var i = 0; i < max; i++) { - this.x = i/100; - } - this.val = val; -} - -function f(max) { - var val = 0.5; - var obj = new g(max,val); - assertSame(val, obj.val); -} - -f(1); -f(1); -%OptimizeFunctionOnNextCall(f); -f(200000); diff --git a/deps/v8/test/mjsunit/regress/regress-126412.js b/deps/v8/test/mjsunit/regress/regress-126412.js deleted file mode 100644 index 0677f70913..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-126412.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"".match(/(A{9999999999}B|C*)*D/); -"C".match(/(A{9999999999}B|C*)*D/); -"".match(/(A{9999999999}B|C*)*/ ); -"C".match(/(A{9999999999}B|C*)*/ ); -"".match(/(9u|(2\`shj{2147483649,}\r|3|f|y|3*)+8\B)\W93+/); -"9u8 ".match(/(9u|(2\`shj{2147483649,}\r|3|f|y|3*)+8\B)\W93+/); diff --git a/deps/v8/test/mjsunit/regress/regress-2030.js b/deps/v8/test/mjsunit/regress/regress-2030.js deleted file mode 100644 index fb5a3d0c46..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2030.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax - -function a() { - this.x = 1; -} -var aa = new a(); -%DebugPrint(aa); - -function b() { - this.z = 23; - this.x = 2; -} -var bb = new b(); -%DebugPrint(bb); - -function f(o) { - return o.x; -} - -assertSame(1, f(aa)); -assertSame(1, f(aa)); -assertSame(2, f(bb)); -assertSame(2, f(bb)); -%OptimizeFunctionOnNextCall(f); -assertSame(1, f(aa)); -assertSame(2, f(bb)); diff --git a/deps/v8/test/mjsunit/regress/regress-2032.js b/deps/v8/test/mjsunit/regress/regress-2032.js deleted file mode 100644 index ad6408d3d6..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2032.js +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// See: http://code.google.com/p/v8/issues/detail?id=2032 - -// Case independent regexp that ends on the first character in a block. -assertTrue(/[@-A]/i.test("a")); -assertTrue(/[@-A]/i.test("A")); -assertTrue(/[@-A]/i.test("@")); - -assertFalse(/[@-A]/.test("a")); -assertTrue(/[@-A]/.test("A")); -assertTrue(/[@-A]/.test("@")); - -assertFalse(/[¿-À]/i.test('¾')); -assertTrue(/[¿-À]/i.test('¿')); -assertTrue(/[¿-À]/i.test('À')); -assertTrue(/[¿-À]/i.test('à')); -assertFalse(/[¿-À]/i.test('á')); -assertFalse(/[¿-À]/i.test('Á')); - -assertFalse(/[¿-À]/.test('¾')); -assertTrue(/[¿-À]/.test('¿')); -assertTrue(/[¿-À]/.test('À')); -assertFalse(/[¿-À]/.test('à')); -assertFalse(/[¿-À]/.test('á')); -assertFalse(/[¿-À]/.test('á')); -assertFalse(/[¿-À]/i.test('Á')); - -assertFalse(/[Ö-×]/i.test('Õ')); -assertTrue(/[Ö-×]/i.test('Ö')); -assertTrue(/[Ö-×]/i.test('ö')); -assertTrue(/[Ö-×]/i.test('×')); -assertFalse(/[Ö-×]/i.test('Ø')); - -assertFalse(/[Ö-×]/.test('Õ')); -assertTrue(/[Ö-×]/.test('Ö')); -assertFalse(/[Ö-×]/.test('ö')); -assertTrue(/[Ö-×]/.test('×')); -assertFalse(/[Ö-×]/.test('Ø')); diff --git a/deps/v8/test/mjsunit/regress/regress-2034.js b/deps/v8/test/mjsunit/regress/regress-2034.js deleted file mode 100644 index c510f97fc3..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2034.js +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --harmony-collections - -var key = {}; -var map = new WeakMap; -Object.preventExtensions(key); - -// Try querying using frozen key. -assertFalse(map.has(key)); -assertSame(undefined, map.get(key)); - -// Try adding using frozen key. -map.set(key, 1); -assertTrue(map.has(key)); -assertSame(1, map.get(key)); - -// Try deleting using frozen key. -map.delete(key, 1); -assertFalse(map.has(key)); -assertSame(undefined, map.get(key)); diff --git a/deps/v8/test/mjsunit/regress/regress-2054.js b/deps/v8/test/mjsunit/regress/regress-2054.js deleted file mode 100644 index 97b989c944..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2054.js +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Test that we can correctly optimize top level code that contains a -// throw (or return) as it's last statement. - -var N = 1e5; // Number of iterations that trigger optimization. -for (var i = 0; i < N; i++) { - if (i > N) throw new Error; -} diff --git a/deps/v8/test/mjsunit/regress/regress-2055.js b/deps/v8/test/mjsunit/regress/regress-2055.js deleted file mode 100644 index 1eaf62c7da..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2055.js +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Test that array literal boilerplate objects can be transitioned while -// existing un-transitioned clones are still being populated. - -function test1(depth) { - if (--depth < 0) { - return []; - } else { - return [ 0, test1(depth) ]; - } -} -assertEquals([0,[0,[]]], test1(2)); - -function test2(depth) { - if (--depth < 0) { - return []; - } else { - var o = [ 0, test2(depth) ]; - return (depth == 0) ? 0.5 : o; - } -} -assertEquals([0,0.5], test2(2)); diff --git a/deps/v8/test/mjsunit/regress/regress-2058.js b/deps/v8/test/mjsunit/regress/regress-2058.js deleted file mode 100644 index 9a69ea1621..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2058.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// See http://code.google.com/p/v8/issues/detail?id=2058 - -// A match after a replace with a function argument needs to reset -// the flag that determines whether we are using indices or substrings -// to indicate the last match. -"Now is the".replace(/Now (\w+) the/g, function() { - "foo bar".match(/( )/); - assertEquals(RegExp.$1, " "); -}) diff --git a/deps/v8/test/mjsunit/regress/regress-2110.js b/deps/v8/test/mjsunit/regress/regress-2110.js deleted file mode 100644 index d7f78d26a7..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-2110.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax - -var uint8 = new Uint8Array(1); - -function test() { - uint8[0] = 0x800000aa; - assertEquals(0xaa, uint8[0]); -} - -test(); -test(); -test(); -%OptimizeFunctionOnNextCall(test); -test(); - -var uint32 = new Uint32Array(1); - -function test2() { - uint32[0] = 0x80123456789abcde; - assertEquals(0x789ac000, uint32[0]); -} - -test2(); -test2(); -%OptimizeFunctionOnNextCall(test2); -test2(); diff --git a/deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js b/deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js deleted file mode 100644 index 72110f5be2..0000000000 --- a/deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --allow-natives-syntax --always-opt --expose-gc - -// Test that the elements kind of the boilerplate object is sufficiently -// checked in LFastLiteral, so that unoptimized code can transition the -// boilerplate. The --always-opt flag makes sure that optimized code is -// not thrown away at deoptimization. - -// The switch statement in f() makes sure that f() is not inlined. If we -// start inlining switch statements, we will still catch the bug on the -// final --stress-opt run. - -function f(x) { - switch(x) { - case 1: return 1.4; - case 2: return 1.5; - case 3: return {}; - default: gc(); - } -} - -function g(x) { - return [1.1, 1.2, 1.3, f(x)]; -} - -// Step 1: Optimize g() to contain a FAST_DOUBLE_ELEMENTS boilerplate. -assertEquals([1.1, 1.2, 1.3, 1.4], g(1)); -assertEquals([1.1, 1.2, 1.3, 1.5], g(2)); -%OptimizeFunctionOnNextCall(g); - -// Step 2: Deoptimize g() and transition to FAST_ELEMENTS boilerplate. -assertEquals([1.1, 1.2, 1.3, {}], g(3)); - -// Step 3: Cause a GC while broken clone of boilerplate is on the heap, -// hence causing heap verification to catch it. -assertEquals([1.1, 1.2, 1.3, undefined], g(4)); diff --git a/deps/v8/test/mjsunit/unicodelctest-no-optimization.js b/deps/v8/test/mjsunit/unicodelctest-no-optimization.js deleted file mode 100644 index 3bcb5bf256..0000000000 --- a/deps/v8/test/mjsunit/unicodelctest-no-optimization.js +++ /dev/null @@ -1,4914 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --noregexp-optimization - -// This regexp should pick up all lower case characters. The non-BMP -// characters are coded using explicit surrogate pairs. -var re = /^([a-zªµºß-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ-ĸĺļľŀłńņň-ʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž-ƀƃƅƈƌ-ƍƒƕƙ-ƛƞơƣƥƨƪ-ƫƭưƴƶƹ-ƺƽ-ƿdžljnjǎǐǒǔǖǘǚǜ-ǝǟǡǣǥǧǩǫǭǯ-ǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳ-ȹȼȿ-ɀɂɇɉɋɍɏ-ʓʕ-ʯͱͳͷͻ-ͽΐά-ώϐ-ϑϕ-ϗϙϛϝϟϡϣϥϧϩϫϭϯ-ϳϵϸϻ-ϼа-џѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎ-ӏӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹӻӽӿԁԃԅԇԉԋԍԏԑԓԕԗԙԛԝԟԡԣա-ևᴀ-ᴫᵢ-ᵷᵹ-ᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕ-ẝẟạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹỻỽỿ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶ-ᾷιῂ-ῄῆ-ῇῐ-ΐῖ-ῗῠ-ῧῲ-ῴῶ-ῷⁱⁿℊℎ-ℏℓℯℴℹℼ-ℽⅆ-ⅉⅎↄⰰ-ⱞⱡⱥ-ⱦⱨⱪⱬⱱⱳ-ⱴⱶ-ⱼⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ-ⳤⴀ-ⴥꙁꙃꙅꙇꙉꙋꙍꙏꙑꙓꙕꙗꙙꙛꙝꙟꙣꙥꙧꙩꙫꙭꚁꚃꚅꚇꚉꚋꚍꚏꚑꚓꚕꚗꜣꜥꜧꜩꜫꜭꜯ-ꜱꜳꜵꜷꜹꜻꜽꜿꝁꝃꝅꝇꝉꝋꝍꝏꝑꝓꝕꝗꝙꝛꝝꝟꝡꝣꝥꝧꝩꝫꝭꝯꝱ-ꝸꝺꝼꝿꞁꞃꞅꞇꞌff-stﬓ-ﬗa-z]|\ud801[\udc28-\udc4f]|\ud835[\udc1a-\udc33\udc4e-\udc54\udc56-\udc67\udc82-\udc9b\udcb6-\udcb9\udcbb\udcbd-\udcc3\udcc5-\udccf\udcea-\udd03\udd1e-\udd37\udd52-\udd6b\udd86-\udd9f\uddba-\uddd3\uddee-\ude07\ude22-\ude3b\ude56-\ude6f\ude8a-\udea5\udec2-\udeda\udedc-\udee1\udefc-\udf14\udf16-\udf1b\udf36-\udf4e\udf50-\udf55\udf70-\udf88\udf8a-\udf8f\udfaa-\udfc2\udfc4-\udfc9\udfcb])$/; - - -var answer = get_answer(); -var fuzz_answer = get_fuzz_answer(); - - -for (var i = 0; i < 0x10000; i++) { - var s = String.fromCharCode(i); - assertTrue(!!re.test(s) == !!answer[i]); -} - - -function BuildSurrogatePair(c) { - return String.fromCharCode(+0xd800 + (c >> 10)) + - String.fromCharCode(+0xdc00 + (c & 0x3ff)); -} - -fuzz_index = 0; -fuzz(); - -for (var i = 0x10000; i < 0x110000 && i < answer.length + 256; i++) { - var c = i - 0x10000; - assertTrue(!!re.test(BuildSurrogatePair(c)) == !!answer[i]); -} - -var seed = 49734321; - -function rand() { - // To make the test results predictable, we use a 100% deterministic - // alternative. - // Robert Jenkins' 32 bit integer hash function. - seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff; - seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff; - seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff; - seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff; - seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff; - seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff; - return (seed & 0xffff) -} - - -// Random character. -function rc(last) { - var c = rand(); - // Increase the concentration of problematic values around the page - // edges. - if (rand() & 1) { - c = (c & 0xff80) + (c & 3) - 2; - } - // Increase the concentration of problematic values around the ends. - if (rand() & 31 == 0) c = 0xfff8 + (rand() & 7) - if (rand() & 31 == 0) c = (rand() & 7) - - // Increase the concentration of values near each other. - if (rand() & 1) c = last + (rand() & 15) - 8; - return c & 0xffff; // Only code unit values. -} - - -function fuzz() { - fuzz_index = 0; - seed = 49734321; - for (var i = 0; i < 1000; i++) { - print(i); - var len = rand() & 0x1f; - var ranges = new Array(len); - var last = rand(); - for (var j = 0; j < len; j++) { - ranges.push(last); - last = rc(last); - } - ranges.sort(function (a, b) { return a - b }); - var cc = ""; - for (var j = 0; j < len; j++) { - var ch = String.fromCharCode(ranges[j]); - if (ch == '\\' || ch == ']') ch = '\\' + ch; - cc += ch; - if (j < len - 1 && rand() & 1) cc += '-'; - } - var negated = (last & 2) != 0; - var prefix = negated ? "[^" : "["; - var re = new RegExp(prefix + cc + "]"); - for (var j = 0; j < len; j++) { - retest(re, (ranges[j] - 1), negated); - retest(re, (ranges[j]), negated); - retest(re, (ranges[j] + 1), negated); - } - } -} - - -function retest(re, code, negated) { - var s = String.fromCharCode(code >>> 0); - assertTrue(negated != (!!re.test(s) == !!fuzz_answer[fuzz_index++])); -} - - -function get_fuzz_answer() { - // Test data generated with V8 version 3.7. -return [ - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0, - - - 0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, -]; -} - - -function get_answer() { - // Test data generated with V8 version 3.7. -return [ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , ,1, , , , , , , , , , ,1, , , , ,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, , - 1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, , ,1, ,1, ,1,1, - 1, , ,1, ,1, , ,1, , , ,1,1, , , , ,1, , ,1, , , ,1,1,1, , ,1, , - ,1, ,1, ,1, , ,1, ,1,1, ,1, , ,1, , , ,1, ,1, , ,1,1, , ,1,1,1, - , , , , , ,1, , ,1, , ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, , ,1, ,1, , , ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1, , ,1, , ,1, - 1, ,1, , , , ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , ,1, ,1, , , ,1, , , ,1,1,1, , , - , , , , , , , , , , , , , , , ,1, , , , , , , , , , , , , , , , - , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1, , , ,1,1,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1, ,1, , ,1, , ,1,1, , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, , , , , , , , , ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - , ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1, , , , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1, , , , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1, ,1,1, , , , , , ,1, , - , ,1,1,1, ,1,1, , , , , , , , ,1,1,1,1, , ,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , , , ,1,1,1, ,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , ,1, , , , , , , , , , , , , ,1, - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , ,1, , , ,1,1, , , ,1, , , , , , , , , , , , , - , , , , , , , , , , , , , , ,1, , , , ,1, , , , ,1, , ,1,1, , , - , , , , , ,1,1,1,1, , , , ,1, , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , ,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , - ,1, , , ,1,1, ,1, ,1, ,1, , , , ,1, ,1,1, ,1,1,1,1,1,1,1, , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - , , ,1, ,1, ,1, ,1, ,1, ,1, , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1, ,1, ,1, , ,1, - ,1, ,1, ,1, ,1, , , , ,1, , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1, , , , , , , , , , , , ,1,1,1,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , - , , , , , , , , , , , , , ,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1, ,1, ,1,1,1, - 1,1,1,1, ,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , - , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , - , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1, - 1,1, , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1, ,1,1,1,1,1,1, ,1]; -} diff --git a/deps/v8/test/mjsunit/unicodelctest.js b/deps/v8/test/mjsunit/unicodelctest.js deleted file mode 100644 index 2caaabdcbe..0000000000 --- a/deps/v8/test/mjsunit/unicodelctest.js +++ /dev/null @@ -1,4912 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This regexp should pick up all lower case characters. The non-BMP -// characters are coded using explicit surrogate pairs. -var re = /^([a-zªµºß-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ-ĸĺļľŀłńņň-ʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž-ƀƃƅƈƌ-ƍƒƕƙ-ƛƞơƣƥƨƪ-ƫƭưƴƶƹ-ƺƽ-ƿdžljnjǎǐǒǔǖǘǚǜ-ǝǟǡǣǥǧǩǫǭǯ-ǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳ-ȹȼȿ-ɀɂɇɉɋɍɏ-ʓʕ-ʯͱͳͷͻ-ͽΐά-ώϐ-ϑϕ-ϗϙϛϝϟϡϣϥϧϩϫϭϯ-ϳϵϸϻ-ϼа-џѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎ-ӏӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹӻӽӿԁԃԅԇԉԋԍԏԑԓԕԗԙԛԝԟԡԣա-ևᴀ-ᴫᵢ-ᵷᵹ-ᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕ-ẝẟạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹỻỽỿ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶ-ᾷιῂ-ῄῆ-ῇῐ-ΐῖ-ῗῠ-ῧῲ-ῴῶ-ῷⁱⁿℊℎ-ℏℓℯℴℹℼ-ℽⅆ-ⅉⅎↄⰰ-ⱞⱡⱥ-ⱦⱨⱪⱬⱱⱳ-ⱴⱶ-ⱼⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ-ⳤⴀ-ⴥꙁꙃꙅꙇꙉꙋꙍꙏꙑꙓꙕꙗꙙꙛꙝꙟꙣꙥꙧꙩꙫꙭꚁꚃꚅꚇꚉꚋꚍꚏꚑꚓꚕꚗꜣꜥꜧꜩꜫꜭꜯ-ꜱꜳꜵꜷꜹꜻꜽꜿꝁꝃꝅꝇꝉꝋꝍꝏꝑꝓꝕꝗꝙꝛꝝꝟꝡꝣꝥꝧꝩꝫꝭꝯꝱ-ꝸꝺꝼꝿꞁꞃꞅꞇꞌff-stﬓ-ﬗa-z]|\ud801[\udc28-\udc4f]|\ud835[\udc1a-\udc33\udc4e-\udc54\udc56-\udc67\udc82-\udc9b\udcb6-\udcb9\udcbb\udcbd-\udcc3\udcc5-\udccf\udcea-\udd03\udd1e-\udd37\udd52-\udd6b\udd86-\udd9f\uddba-\uddd3\uddee-\ude07\ude22-\ude3b\ude56-\ude6f\ude8a-\udea5\udec2-\udeda\udedc-\udee1\udefc-\udf14\udf16-\udf1b\udf36-\udf4e\udf50-\udf55\udf70-\udf88\udf8a-\udf8f\udfaa-\udfc2\udfc4-\udfc9\udfcb])$/; - - -var answer = get_answer(); -var fuzz_answer = get_fuzz_answer(); - - -for (var i = 0; i < 0x10000; i++) { - var s = String.fromCharCode(i); - assertTrue(!!re.test(s) == !!answer[i]); -} - - -function BuildSurrogatePair(c) { - return String.fromCharCode(+0xd800 + (c >> 10)) + - String.fromCharCode(+0xdc00 + (c & 0x3ff)); -} - -fuzz_index = 0; -fuzz(); - -for (var i = 0x10000; i < 0x110000 && i < answer.length + 256; i++) { - var c = i - 0x10000; - assertTrue(!!re.test(BuildSurrogatePair(c)) == !!answer[i]); -} - -var seed = 49734321; - -function rand() { - // To make the test results predictable, we use a 100% deterministic - // alternative. - // Robert Jenkins' 32 bit integer hash function. - seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff; - seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff; - seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff; - seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff; - seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff; - seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff; - return (seed & 0xffff) -} - - -// Random character. -function rc(last) { - var c = rand(); - // Increase the concentration of problematic values around the page - // edges. - if (rand() & 1) { - c = (c & 0xff80) + (c & 3) - 2; - } - // Increase the concentration of problematic values around the ends. - if (rand() & 31 == 0) c = 0xfff8 + (rand() & 7) - if (rand() & 31 == 0) c = (rand() & 7) - - // Increase the concentration of values near each other. - if (rand() & 1) c = last + (rand() & 15) - 8; - return c & 0xffff; // Only code unit values. -} - - -function fuzz() { - fuzz_index = 0; - seed = 49734321; - for (var i = 0; i < 1000; i++) { - var len = rand() & 0x1f; - var ranges = new Array(len); - var last = rand(); - for (var j = 0; j < len; j++) { - ranges.push(last); - last = rc(last); - } - ranges.sort(function (a, b) { return a - b }); - var cc = ""; - for (var j = 0; j < len; j++) { - var ch = String.fromCharCode(ranges[j]); - if (ch == '\\' || ch == ']') ch = '\\' + ch; - cc += ch; - if (j < len - 1 && rand() & 1) cc += '-'; - } - var negated = (last & 2) != 0; - var prefix = negated ? "[^" : "["; - var re = new RegExp(prefix + cc + "]"); - for (var j = 0; j < len; j++) { - retest(re, (ranges[j] - 1), negated); - retest(re, (ranges[j]), negated); - retest(re, (ranges[j] + 1), negated); - } - } -} - - -function retest(re, code, negated) { - var s = String.fromCharCode(code >>> 0); - assertTrue(negated != (!!re.test(s) == !!fuzz_answer[fuzz_index++])); -} - - -function get_fuzz_answer() { - // Test data generated with V8 version 3.7. -return [ - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0, - - - 0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0, - 0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0, - 0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0, - - 0,1,1,1,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0, - 0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0, - 0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0, - 0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0, -]; -} - - -function get_answer() { - // Test data generated with V8 version 3.7. -return [ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , ,1, , , , , , , , , , ,1, , , , ,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, , - 1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, , ,1, ,1, ,1,1, - 1, , ,1, ,1, , ,1, , , ,1,1, , , , ,1, , ,1, , , ,1,1,1, , ,1, , - ,1, ,1, ,1, , ,1, ,1,1, ,1, , ,1, , , ,1, ,1, , ,1,1, , ,1,1,1, - , , , , , ,1, , ,1, , ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, , ,1, ,1, , , ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1, , ,1, , ,1, - 1, ,1, , , , ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , ,1, ,1, , , ,1, , , ,1,1,1, , , - , , , , , , , , , , , , , , , ,1, , , , , , , , , , , , , , , , - , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1, , , ,1,1,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1, ,1, , ,1, , ,1,1, , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, , , , , , , , , ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - , ,1, ,1, ,1, ,1, ,1, ,1, ,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1, , , , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1, , , , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1,1,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , ,1,1,1,1,1, ,1,1, , , , , , ,1, , - , ,1,1,1, ,1,1, , , , , , , , ,1,1,1,1, , ,1,1, , , , , , , , , - 1,1,1,1,1,1,1,1, , , , , , , , , , ,1,1,1, ,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , ,1, , , , , , , , , , , , , ,1, - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , ,1, , , ,1,1, , , ,1, , , , , , , , , , , , , - , , , , , , , , , , , , , , ,1, , , , ,1, , , , ,1, , ,1,1, , , - , , , , , ,1,1,1,1, , , , ,1, , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , ,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , - ,1, , , ,1,1, ,1, ,1, ,1, , , , ,1, ,1,1, ,1,1,1,1,1,1,1, , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - , , ,1, ,1, ,1, ,1, ,1, ,1, , , , , , , , , , , , , , , , , , , - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, - ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1, ,1,1,1,1,1,1,1,1, ,1, ,1, , ,1, - ,1, ,1, ,1, ,1, , , , ,1, , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - 1,1,1,1,1,1,1, , , , , , , , , , , , ,1,1,1,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , - , , , , , , , , , , , , , ,1,1,1,1,1,1,1, ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1, ,1, ,1,1,1, - 1,1,1,1, ,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , - , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , - , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , - , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1, , , , , , , , , , , , , , , , , , , , , , , , , , , - , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1, - 1,1, , , , , , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , - , , , , , , , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , , , , , , , - , , , , , , , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1, ,1,1,1,1,1,1, , , , , , , , , , , , , , , , , - , , , , , , , , , ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1, ,1,1,1,1,1,1, ,1]; -} diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status index c30be5e095..e64959acfc 100644 --- a/deps/v8/test/mozilla/mozilla.status +++ b/deps/v8/test/mozilla/mozilla.status @@ -592,20 +592,6 @@ js1_5/Regress/regress-416737-01: FAIL_OK js1_5/Regress/regress-416737-02: FAIL_OK -# Illegal escape-sequences in string literals. Has already been fixed -# by most engines (i.e. V8, JSC, Opera and FF). -ecma/Array/15.4.5.1-1: FAIL_OK -ecma/LexicalConventions/7.7.4: FAIL_OK -ecma_2/RegExp/hex-001: FAIL_OK -js1_2/regexp/hexadecimal: FAIL_OK - - -# The source field of RegExp objects is properly escaped. We match JSC. -ecma_2/RegExp/constructor-001: FAIL_OK -ecma_2/RegExp/function-001: FAIL_OK -ecma_2/RegExp/properties-001: FAIL_OK - - ##################### FAILING TESTS ##################### # This section is for tests that fail in V8 and pass in JSC. diff --git a/deps/v8/test/sputnik/sputnik.status b/deps/v8/test/sputnik/sputnik.status index 52d126e65b..a4c7d57ff0 100644 --- a/deps/v8/test/sputnik/sputnik.status +++ b/deps/v8/test/sputnik/sputnik.status @@ -52,14 +52,36 @@ S15.10.2.11_A1_T3: FAIL # We are more lenient in which string character escapes we allow than # the spec (7.8.4 p. 19) wants us to be. This is for compatibility. -S7.8.4_A4.3_T1: FAIL_OK S7.8.4_A4.3_T2: FAIL_OK -S7.8.4_A4.3_T3: FAIL_OK +S7.8.4_A4.3_T2: FAIL_OK +S7.8.4_A6.2_T2: FAIL_OK +S7.8.4_A6.1_T4: FAIL_OK S7.8.4_A4.3_T4: FAIL_OK -S7.8.4_A6.4_T1: FAIL_OK +S7.8.4_A7.2_T2: FAIL_OK +S7.8.4_A7.1_T4: FAIL_OK S7.8.4_A6.4_T2: FAIL_OK -S7.8.4_A7.4_T1: FAIL_OK S7.8.4_A7.4_T2: FAIL_OK +S7.8.4_A7.2_T4: FAIL_OK +S7.8.4_A4.3_T6: FAIL_OK +S7.8.4_A7.2_T6: FAIL_OK +S7.8.4_A4.3_T1: FAIL_OK +S7.8.4_A6.2_T1: FAIL_OK +S7.8.4_A4.3_T3: FAIL_OK +S7.8.4_A7.2_T1: FAIL_OK +S7.8.4_A6.4_T1: FAIL_OK +S7.8.4_A7.2_T3: FAIL_OK +S7.8.4_A7.4_T1: FAIL_OK +S7.8.4_A4.3_T5: FAIL_OK +S7.8.4_A7.2_T5: FAIL_OK +S7.8.4_A4.3_T1: FAIL_OK +S7.8.4_A6.2_T1: FAIL_OK +S7.8.4_A4.3_T3: FAIL_OK +S7.8.4_A7.2_T1: FAIL_OK +S7.8.4_A6.4_T1: FAIL_OK +S7.8.4_A7.2_T3: FAIL_OK +S7.8.4_A7.4_T1: FAIL_OK +S7.8.4_A4.3_T5: FAIL_OK +S7.8.4_A7.2_T5: FAIL_OK # Sputnik expects unicode escape sequences in RegExp flags to be interpreted. # The specification requires them to be passed uninterpreted to the RegExp @@ -124,16 +146,6 @@ S15.3.4.2_A1_T1: FAIL_OK S8.5_A2.2: PASS, FAIL if $system == linux, FAIL if $system == macos S8.5_A2.1: PASS, FAIL if $system == linux, FAIL if $system == macos -# The source field of RegExp objects is properly escaped. We match JSC. -S15.10.4.1_A3_T1: FAIL_OK -S15.10.4.1_A3_T2: FAIL_OK -S15.10.4.1_A3_T3: FAIL_OK -S15.10.4.1_A3_T4: FAIL_OK -S15.10.4.1_A3_T5: FAIL_OK -S15.10.4.1_A4_T2: FAIL_OK -S15.10.4.1_A4_T3: FAIL_OK -S15.10.4.1_A4_T5: FAIL_OK - ##################### ES3 TESTS ######################### # These tests check for ES3 semantics, and differ from ES5. # When we follow ES5 semantics, it's ok to fail the test. diff --git a/deps/v8/test/test262/README b/deps/v8/test/test262/README index 59e7f5eb8b..dae18433a5 100644 --- a/deps/v8/test/test262/README +++ b/deps/v8/test/test262/README @@ -4,11 +4,11 @@ tests from http://hg.ecmascript.org/tests/test262 -at revision 334 as 'data' in this directory. Using later version +at revision 309 as 'data' in this directory. Using later version may be possible but the tests are only known to pass (and indeed run) with that revision. -hg clone -r 334 http://hg.ecmascript.org/tests/test262 data +hg clone -r 309 http://hg.ecmascript.org/tests/test262 data If you do update to a newer revision you may have to change the test harness adapter code since it uses internal functionality from the diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index c75528995d..3f395bdcd1 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -33,18 +33,7 @@ def FAIL_OK = FAIL, OKAY # '__proto__' should be treated as a normal property in JSON. S15.12.2_A1: FAIL -# Sequencing of getter side effects on receiver and argument properties -# is wrong. The receiver callback should be called before any arguments -# are evaluated. -# V8 Bug: http://code.google.com/p/v8/issues/detail?id=691 -11.2.3-3_3: FAIL - -# Prototypal inheritance of properties does not maintain accessibility. -# The [[CanPut]] operation should traverse the prototype chain to -# determine whether given property is writable or not. # V8 Bug: http://code.google.com/p/v8/issues/detail?id=1475 -8.14.4-8-b_1: FAIL -8.14.4-8-b_2: FAIL 15.2.3.6-4-405: FAIL 15.2.3.6-4-410: FAIL 15.2.3.6-4-415: FAIL @@ -63,6 +52,19 @@ S15.1.2.2_A5.1_T1: FAIL_OK S15.8.2.16_A7: PASS || FAIL_OK S15.8.2.18_A7: PASS || FAIL_OK +# We are more lenient in which string character escapes we allow than +# the spec (7.8.4 p. 19) wants us to be. This is for compatibility. +S7.8.4_A6.1_T4: FAIL_OK +S7.8.4_A6.2_T1: FAIL_OK +S7.8.4_A6.2_T2: FAIL_OK +S7.8.4_A7.1_T4: FAIL_OK +S7.8.4_A7.2_T1: FAIL_OK +S7.8.4_A7.2_T2: FAIL_OK +S7.8.4_A7.2_T3: FAIL_OK +S7.8.4_A7.2_T4: FAIL_OK +S7.8.4_A7.2_T5: FAIL_OK +S7.8.4_A7.2_T6: FAIL_OK + # Linux for ia32 (and therefore simulators) default to extended 80 bit floating # point formats, so these tests checking 64-bit FP precision fail. The other # platforms/arch's pass these tests. diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py index 2c9bf06f14..b05b205dd6 100644 --- a/deps/v8/test/test262/testcfg.py +++ b/deps/v8/test/test262/testcfg.py @@ -1,4 +1,4 @@ -# Copyright 2012 the V8 project authors. All rights reserved. +# Copyright 2011 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: @@ -31,11 +31,12 @@ import os from os.path import join, exists import urllib import hashlib +import sys import tarfile -TEST_262_ARCHIVE_REVISION = 'fb327c439e20' # This is the r334 revision. -TEST_262_ARCHIVE_MD5 = '307acd166ec34629592f240dc12d57ed' +TEST_262_ARCHIVE_REVISION = '3a890174343c' # This is the r309 revision. +TEST_262_ARCHIVE_MD5 = 'be5d4cfbe69cef70430907b8f3a92b50' TEST_262_URL = 'http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2' TEST_262_HARNESS = ['sta.js'] @@ -103,25 +104,27 @@ class Test262TestConfiguration(test.TestConfiguration): revision = TEST_262_ARCHIVE_REVISION archive_url = TEST_262_URL % revision archive_name = join(self.root, 'test262-%s.tar.bz2' % revision) - directory_name = join(self.root, 'data') - directory_old_name = join(self.root, 'data.old') - if not exists(archive_name): - print "Downloading test data from %s ..." % archive_url - urllib.urlretrieve(archive_url, archive_name) - if exists(directory_name): - os.rename(directory_name, directory_old_name) - if not exists(directory_name): - print "Extracting test262-%s.tar.bz2 ..." % revision - md5 = hashlib.md5() - with open(archive_name,'rb') as f: - for chunk in iter(lambda: f.read(8192), ''): - md5.update(chunk) - if md5.hexdigest() != TEST_262_ARCHIVE_MD5: - os.remove(archive_name) - raise Exception("Hash mismatch of test data file") - archive = tarfile.open(archive_name, 'r:bz2') - archive.extractall(join(self.root)) - os.rename(join(self.root, 'test262-%s' % revision), directory_name) + directory_name = join(self.root, "test262-%s" % revision) + if not exists(directory_name) or not exists(archive_name): + if not exists(archive_name): + print "Downloading test data from %s ..." % archive_url + urllib.urlretrieve(archive_url, archive_name) + if not exists(directory_name): + print "Extracting test262-%s.tar.bz2 ..." % revision + md5 = hashlib.md5() + with open(archive_name,'rb') as f: + for chunk in iter(lambda: f.read(8192), ''): + md5.update(chunk) + if md5.hexdigest() != TEST_262_ARCHIVE_MD5: + raise Exception("Hash mismatch of test data file") + archive = tarfile.open(archive_name, 'r:bz2') + if sys.platform in ('win32', 'cygwin'): + # Magic incantation to allow longer path names on Windows. + archive.extractall(u'\\\\?\\%s' % self.root) + else: + archive.extractall(self.root) + if not exists(join(self.root, 'data')): + os.symlink(directory_name, join(self.root, 'data')) def GetBuildRequirements(self): return ['d8'] diff --git a/deps/v8/tools/check-static-initializers.sh b/deps/v8/tools/check-static-initializers.sh index e6da828765..1103a97787 100644 --- a/deps/v8/tools/check-static-initializers.sh +++ b/deps/v8/tools/check-static-initializers.sh @@ -37,14 +37,19 @@ expected_static_init_count=3 v8_root=$(readlink -f $(dirname $BASH_SOURCE)/../) -d8="${v8_root}/d8" + +if [ -n "$1" ] ; then + d8="${v8_root}/$1" +else + d8="${v8_root}/d8" +fi if [ ! -f "$d8" ]; then - echo "Please build the project with SCons." + echo "d8 binary not found: $d8" exit 1 fi -static_inits=$(nm "$d8" | grep _GLOBAL__I | awk '{ print $NF; }') +static_inits=$(nm "$d8" | grep _GLOBAL_ | grep _I_ | awk '{ print $NF; }') static_init_count=$(echo "$static_inits" | wc -l) @@ -52,4 +57,7 @@ if [ $static_init_count -gt $expected_static_init_count ]; then echo "Too many static initializers." echo "$static_inits" exit 1 +else + echo "Static initializer check passed ($static_init_count initializers)." + exit 0 fi diff --git a/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp index 46f85fe1ff..538b7ef5c3 100644 --- a/deps/v8/tools/gyp/v8.gyp +++ b/deps/v8/tools/gyp/v8.gyp @@ -59,11 +59,6 @@ '../../src/v8dll-main.cc', ], 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'OTHER_LDFLAGS': ['-dynamiclib', '-all_load'] - }, - }], ['OS=="win"', { 'defines': [ 'BUILDING_V8_SHARED', @@ -365,7 +360,7 @@ '../../src/jsregexp.h', '../../src/isolate.cc', '../../src/isolate.h', - '../../src/lazy-instance.h', + '../../src/lazy-instance.h' '../../src/list-inl.h', '../../src/list.h', '../../src/lithium.cc', diff --git a/deps/v8/tools/merge-to-branch.sh b/deps/v8/tools/merge-to-branch.sh index aa590a313c..aa590a313c 100644..100755 --- a/deps/v8/tools/merge-to-branch.sh +++ b/deps/v8/tools/merge-to-branch.sh diff --git a/deps/v8/tools/presubmit.py b/deps/v8/tools/presubmit.py index c606e42e69..b923dd0438 100755 --- a/deps/v8/tools/presubmit.py +++ b/deps/v8/tools/presubmit.py @@ -114,15 +114,12 @@ def CppLintWorker(command): while True: out_line = process.stderr.readline() if out_line == '' and process.poll() != None: - if error_count == -1: - print "Failed to process %s" % command.pop() - return 1 break m = LINT_OUTPUT_PATTERN.match(out_line) if m: out_lines += out_line error_count += 1 - sys.stdout.write(out_lines) + sys.stderr.write(out_lines) return error_count except KeyboardInterrupt: process.kill() @@ -303,7 +300,8 @@ class SourceProcessor(SourceFileProcessor): or (name == 'third_party') or (name == 'gyp') or (name == 'out') - or (name == 'obj')) + or (name == 'obj') + or (name == 'DerivedSources')) IGNORE_COPYRIGHTS = ['cpplint.py', 'earley-boyer.js', diff --git a/deps/v8/tools/push-to-trunk.sh b/deps/v8/tools/push-to-trunk.sh index ff6dd1d776..3fb5b34ed3 100755 --- a/deps/v8/tools/push-to-trunk.sh +++ b/deps/v8/tools/push-to-trunk.sh @@ -130,7 +130,6 @@ if [ $START_STEP -le $CURRENT_STEP ] ; then | grep "^BUG=" | grep -v "BUG=$" | grep -v "BUG=none$" \ | sed -e 's/^/ /' \ | sed -e 's/BUG=v8:\(.*\)$/(issue \1)/' \ - | sed -e 's/BUG=chromium:\(.*\)$/(Chromium issue \1)/' \ | sed -e 's/BUG=\(.*\)$/(Chromium issue \1)/' \ >> "$CHANGELOG_ENTRY_FILE" # Append the commit's author for reference. @@ -321,14 +320,6 @@ if [ $START_STEP -le $CURRENT_STEP ] ; then || die "'git svn tag' failed." fi -if [ -z "$CHROME_PATH" ] ; then - echo ">>> (asking for Chromium checkout)" - echo -n "Do you have a \"NewGit\" Chromium checkout and want this script \ -to automate creation of the roll CL? If yes, enter the path to (and including) \ -the \"src\" directory here, otherwise just press <Return>: " - read CHROME_PATH -fi - if [ -n "$CHROME_PATH" ] ; then let CURRENT_STEP+=1 diff --git a/deps/v8/tools/test-wrapper-gypbuild.py b/deps/v8/tools/test-wrapper-gypbuild.py index fda4105a98..eda2459173 100755 --- a/deps/v8/tools/test-wrapper-gypbuild.py +++ b/deps/v8/tools/test-wrapper-gypbuild.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2011 the V8 project authors. All rights reserved. +# 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: @@ -56,6 +56,9 @@ def BuildOptions(): result.add_option("--no-presubmit", help='Skip presubmit checks', default=False, action="store_true") + result.add_option("--buildbot", + help='Adapt to path structure used on buildbots', + default=False, action="store_true") # Flags this wrapper script handles itself: result.add_option("-m", "--mode", @@ -144,14 +147,16 @@ def ProcessOptions(options): options.mode = options.mode.split(',') options.arch = options.arch.split(',') for mode in options.mode: - if not mode in ['debug', 'release']: + if not mode.lower() in ['debug', 'release']: print "Unknown mode %s" % mode return False for arch in options.arch: if not arch in ['ia32', 'x64', 'arm', 'mips']: print "Unknown architecture %s" % arch return False - + if options.buildbot: + # Buildbots run presubmit tests as a separate step. + options.no_presubmit = True return True @@ -213,22 +218,26 @@ def Main(): return 1 workspace = abspath(join(dirname(sys.argv[0]), '..')) + returncodes = 0 if not options.no_presubmit: print ">>> running presubmit tests" - subprocess.call([workspace + '/tools/presubmit.py']) + returncodes += subprocess.call([workspace + '/tools/presubmit.py']) args_for_children = [workspace + '/tools/test.py'] + PassOnOptions(options) args_for_children += ['--no-build', '--build-system=gyp'] for arg in args: args_for_children += [arg] - returncodes = 0 env = os.environ for mode in options.mode: for arch in options.arch: print ">>> running tests for %s.%s" % (arch, mode) - shellpath = workspace + '/' + options.outdir + '/' + arch + '.' + mode + if options.buildbot: + shellpath = workspace + '/' + options.outdir + '/' + mode + mode = mode.lower() + else: + shellpath = workspace + '/' + options.outdir + '/' + arch + '.' + mode env['LD_LIBRARY_PATH'] = shellpath + '/lib.target' shell = shellpath + "/d8" child = subprocess.Popen(' '.join(args_for_children + |