Upgrade V8 to 3.11.1
authorisaacs <i@izs.me>
Wed, 16 May 2012 02:53:16 +0000 (19:53 -0700)
committerisaacs <i@izs.me>
Wed, 16 May 2012 21:22:33 +0000 (14:22 -0700)
297 files changed:
deps/v8/AUTHORS
deps/v8/ChangeLog
deps/v8/DEPS [new file with mode: 0644]
deps/v8/Makefile
deps/v8/SConstruct
deps/v8/build/armu.gypi [deleted file]
deps/v8/build/common.gypi
deps/v8/build/gyp_v8
deps/v8/build/mipsu.gypi [deleted file]
deps/v8/build/standalone.gypi
deps/v8/include/v8-profiler.h
deps/v8/include/v8.h
deps/v8/samples/lineprocessor.cc
deps/v8/samples/samples.gyp
deps/v8/samples/shell.cc
deps/v8/src/api.cc
deps/v8/src/api.h
deps/v8/src/apiutils.h
deps/v8/src/arguments.h
deps/v8/src/arm/code-stubs-arm.cc
deps/v8/src/arm/debug-arm.cc
deps/v8/src/arm/deoptimizer-arm.cc
deps/v8/src/arm/full-codegen-arm.cc
deps/v8/src/arm/ic-arm.cc
deps/v8/src/arm/lithium-arm.cc
deps/v8/src/arm/lithium-arm.h
deps/v8/src/arm/lithium-codegen-arm.cc
deps/v8/src/arm/lithium-codegen-arm.h
deps/v8/src/arm/macro-assembler-arm.cc
deps/v8/src/arm/macro-assembler-arm.h
deps/v8/src/arm/regexp-macro-assembler-arm.cc
deps/v8/src/arm/regexp-macro-assembler-arm.h
deps/v8/src/arm/stub-cache-arm.cc
deps/v8/src/array.js
deps/v8/src/assembler.cc
deps/v8/src/assembler.h
deps/v8/src/ast.cc
deps/v8/src/ast.h
deps/v8/src/bootstrapper.cc
deps/v8/src/builtins.cc
deps/v8/src/builtins.h
deps/v8/src/bytecodes-irregexp.h
deps/v8/src/code-stubs.cc
deps/v8/src/code-stubs.h
deps/v8/src/compiler-intrinsics.h
deps/v8/src/compiler.cc
deps/v8/src/contexts.h
deps/v8/src/conversions-inl.h
deps/v8/src/d8.cc
deps/v8/src/d8.h
deps/v8/src/d8.js
deps/v8/src/date.js
deps/v8/src/debug-agent.cc
deps/v8/src/debug-debugger.js
deps/v8/src/debug.cc
deps/v8/src/debug.h
deps/v8/src/double.h
deps/v8/src/elements.cc
deps/v8/src/elements.h
deps/v8/src/extensions/externalize-string-extension.cc
deps/v8/src/extensions/gc-extension.cc
deps/v8/src/factory.cc
deps/v8/src/factory.h
deps/v8/src/flag-definitions.h
deps/v8/src/frames.cc
deps/v8/src/frames.h
deps/v8/src/full-codegen.cc
deps/v8/src/full-codegen.h
deps/v8/src/handles.cc
deps/v8/src/hashmap.h
deps/v8/src/heap-inl.h
deps/v8/src/heap-profiler.cc
deps/v8/src/heap-profiler.h
deps/v8/src/heap.cc
deps/v8/src/heap.h
deps/v8/src/hydrogen-instructions.cc
deps/v8/src/hydrogen-instructions.h
deps/v8/src/hydrogen.cc
deps/v8/src/hydrogen.h
deps/v8/src/ia32/assembler-ia32.h
deps/v8/src/ia32/builtins-ia32.cc
deps/v8/src/ia32/code-stubs-ia32.cc
deps/v8/src/ia32/codegen-ia32.cc
deps/v8/src/ia32/debug-ia32.cc
deps/v8/src/ia32/deoptimizer-ia32.cc
deps/v8/src/ia32/full-codegen-ia32.cc
deps/v8/src/ia32/ic-ia32.cc
deps/v8/src/ia32/lithium-codegen-ia32.cc
deps/v8/src/ia32/lithium-codegen-ia32.h
deps/v8/src/ia32/lithium-ia32.cc
deps/v8/src/ia32/lithium-ia32.h
deps/v8/src/ia32/macro-assembler-ia32.cc
deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
deps/v8/src/ia32/regexp-macro-assembler-ia32.h
deps/v8/src/ia32/stub-cache-ia32.cc
deps/v8/src/ic.cc
deps/v8/src/ic.h
deps/v8/src/incremental-marking-inl.h
deps/v8/src/incremental-marking.cc
deps/v8/src/incremental-marking.h
deps/v8/src/interface.cc
deps/v8/src/interface.h
deps/v8/src/interpreter-irregexp.cc
deps/v8/src/isolate.cc
deps/v8/src/isolate.h
deps/v8/src/jsregexp.cc
deps/v8/src/jsregexp.h
deps/v8/src/lazy-instance.h
deps/v8/src/list-inl.h
deps/v8/src/list.h
deps/v8/src/lithium-allocator.cc
deps/v8/src/lithium.cc
deps/v8/src/lithium.h
deps/v8/src/liveedit-debugger.js
deps/v8/src/liveedit.cc
deps/v8/src/log.cc
deps/v8/src/log.h
deps/v8/src/macros.py
deps/v8/src/mark-compact.cc
deps/v8/src/mark-compact.h
deps/v8/src/math.js
deps/v8/src/messages.js
deps/v8/src/mips/assembler-mips.cc
deps/v8/src/mips/assembler-mips.h
deps/v8/src/mips/code-stubs-mips.cc
deps/v8/src/mips/constants-mips.h
deps/v8/src/mips/debug-mips.cc
deps/v8/src/mips/deoptimizer-mips.cc
deps/v8/src/mips/full-codegen-mips.cc
deps/v8/src/mips/ic-mips.cc
deps/v8/src/mips/lithium-codegen-mips.cc
deps/v8/src/mips/lithium-codegen-mips.h
deps/v8/src/mips/lithium-gap-resolver-mips.cc
deps/v8/src/mips/lithium-mips.cc
deps/v8/src/mips/lithium-mips.h
deps/v8/src/mips/macro-assembler-mips.cc
deps/v8/src/mips/regexp-macro-assembler-mips.cc
deps/v8/src/mips/regexp-macro-assembler-mips.h
deps/v8/src/mips/stub-cache-mips.cc
deps/v8/src/mirror-debugger.js
deps/v8/src/objects-debug.cc
deps/v8/src/objects-inl.h
deps/v8/src/objects-printer.cc
deps/v8/src/objects-visiting-inl.h
deps/v8/src/objects-visiting.cc
deps/v8/src/objects-visiting.h
deps/v8/src/objects.cc
deps/v8/src/objects.h
deps/v8/src/parser.cc
deps/v8/src/platform-cygwin.cc
deps/v8/src/platform-freebsd.cc
deps/v8/src/platform-linux.cc
deps/v8/src/platform-macos.cc
deps/v8/src/platform-nullos.cc
deps/v8/src/platform-openbsd.cc
deps/v8/src/platform-posix.cc
deps/v8/src/platform-posix.h [new file with mode: 0644]
deps/v8/src/platform-solaris.cc
deps/v8/src/platform-win32.cc
deps/v8/src/platform.h
deps/v8/src/preparser.cc
deps/v8/src/preparser.h
deps/v8/src/profile-generator-inl.h
deps/v8/src/profile-generator.cc
deps/v8/src/profile-generator.h
deps/v8/src/property.h
deps/v8/src/regexp-macro-assembler-irregexp-inl.h
deps/v8/src/regexp-macro-assembler-irregexp.cc
deps/v8/src/regexp-macro-assembler-irregexp.h
deps/v8/src/regexp-macro-assembler-tracer.cc
deps/v8/src/regexp-macro-assembler-tracer.h
deps/v8/src/regexp-macro-assembler.h
deps/v8/src/regexp.js
deps/v8/src/rewriter.cc
deps/v8/src/runtime-profiler.cc
deps/v8/src/runtime-profiler.h
deps/v8/src/runtime.cc
deps/v8/src/runtime.h
deps/v8/src/runtime.js
deps/v8/src/scanner.cc
deps/v8/src/scanner.h
deps/v8/src/scopeinfo.cc
deps/v8/src/scopes.cc
deps/v8/src/scopes.h
deps/v8/src/serialize.cc
deps/v8/src/small-pointer-list.h
deps/v8/src/spaces-inl.h
deps/v8/src/spaces.cc
deps/v8/src/spaces.h
deps/v8/src/string.js
deps/v8/src/stub-cache.cc
deps/v8/src/utils.cc
deps/v8/src/utils.h
deps/v8/src/v8-counters.h
deps/v8/src/v8.cc
deps/v8/src/v8globals.h
deps/v8/src/version.cc
deps/v8/src/x64/assembler-x64.h
deps/v8/src/x64/code-stubs-x64.cc
deps/v8/src/x64/debug-x64.cc
deps/v8/src/x64/deoptimizer-x64.cc
deps/v8/src/x64/disasm-x64.cc
deps/v8/src/x64/full-codegen-x64.cc
deps/v8/src/x64/ic-x64.cc
deps/v8/src/x64/lithium-codegen-x64.cc
deps/v8/src/x64/lithium-codegen-x64.h
deps/v8/src/x64/lithium-x64.cc
deps/v8/src/x64/lithium-x64.h
deps/v8/src/x64/macro-assembler-x64.cc
deps/v8/src/x64/macro-assembler-x64.h
deps/v8/src/x64/regexp-macro-assembler-x64.cc
deps/v8/src/x64/regexp-macro-assembler-x64.h
deps/v8/src/x64/stub-cache-x64.cc
deps/v8/test/cctest/test-accessors.cc
deps/v8/test/cctest/test-alloc.cc
deps/v8/test/cctest/test-api.cc
deps/v8/test/cctest/test-debug.cc
deps/v8/test/cctest/test-decls.cc
deps/v8/test/cctest/test-disasm-x64.cc
deps/v8/test/cctest/test-double.cc
deps/v8/test/cctest/test-heap-profiler.cc
deps/v8/test/cctest/test-heap.cc
deps/v8/test/cctest/test-list.cc
deps/v8/test/cctest/test-mark-compact.cc
deps/v8/test/cctest/test-regexp.cc
deps/v8/test/cctest/test-spaces.cc
deps/v8/test/cctest/test-strings.cc
deps/v8/test/cctest/test-thread-termination.cc
deps/v8/test/cctest/test-weakmaps.cc
deps/v8/test/cctest/testcfg.py
deps/v8/test/mjsunit/accessor-map-sharing.js [new file with mode: 0644]
deps/v8/test/mjsunit/array-bounds-check-removal.js [new file with mode: 0644]
deps/v8/test/mjsunit/big-array-literal.js
deps/v8/test/mjsunit/compiler/alloc-object-huge.js
deps/v8/test/mjsunit/compiler/inline-arguments.js
deps/v8/test/mjsunit/compiler/inline-construct.js
deps/v8/test/mjsunit/compiler/literals.js
deps/v8/test/mjsunit/compiler/optimize-bitnot.js [new file with mode: 0644]
deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
deps/v8/test/mjsunit/debug-function-scopes.js [new file with mode: 0644]
deps/v8/test/mjsunit/debug-liveedit-stack-padding.js [new file with mode: 0644]
deps/v8/test/mjsunit/debug-scripts-request.js
deps/v8/test/mjsunit/debug-stepin-builtin-callback.js [new file with mode: 0644]
deps/v8/test/mjsunit/declare-locally.js
deps/v8/test/mjsunit/error-constructors.js
deps/v8/test/mjsunit/harmony/debug-function-scopes.js [new file with mode: 0644]
deps/v8/test/mjsunit/harmony/module-linking.js [new file with mode: 0644]
deps/v8/test/mjsunit/harmony/module-parsing.js
deps/v8/test/mjsunit/harmony/module-resolution.js
deps/v8/test/mjsunit/math-floor-of-div.js [new file with mode: 0644]
deps/v8/test/mjsunit/mjsunit.js
deps/v8/test/mjsunit/mjsunit.status
deps/v8/test/mjsunit/regexp-capture-3.js
deps/v8/test/mjsunit/regress/regress-1119.js
deps/v8/test/mjsunit/regress/regress-115452.js
deps/v8/test/mjsunit/regress/regress-1170.js
deps/v8/test/mjsunit/regress/regress-117409.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-119609.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-120099.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-121407.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-1217.js
deps/v8/test/mjsunit/regress/regress-123512.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-123919.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-124594.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-125515.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-126412.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-1639-2.js
deps/v8/test/mjsunit/regress/regress-1639.js
deps/v8/test/mjsunit/regress/regress-2027.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2030.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2032.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2034.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2045.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2054.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2055.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2056.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2058.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-2110.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-crbug-122271.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-crbug-126414.js [new file with mode: 0644]
deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js [new file with mode: 0644]
deps/v8/test/mjsunit/unicodelctest-no-optimization.js [new file with mode: 0644]
deps/v8/test/mjsunit/unicodelctest.js [new file with mode: 0644]
deps/v8/test/mozilla/mozilla.status
deps/v8/test/sputnik/sputnik.status
deps/v8/test/test262/README
deps/v8/test/test262/test262.status
deps/v8/test/test262/testcfg.py
deps/v8/tools/check-static-initializers.sh
deps/v8/tools/common-includes.sh
deps/v8/tools/grokdump.py
deps/v8/tools/gyp/v8.gyp
deps/v8/tools/merge-to-branch.sh
deps/v8/tools/presubmit.py
deps/v8/tools/push-to-trunk.sh
deps/v8/tools/test-wrapper-gypbuild.py

index dfefad1..6e46b3d 100644 (file)
@@ -23,6 +23,7 @@ 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>
index 2240ec0..c52a5ab 100644 (file)
@@ -1,3 +1,208 @@
+2012-05-15: Version 3.11.1
+
+        Added a readbuffer function to d8 that reads a file into an ArrayBuffer.
+
+        Fix freebsd build. (V8 issue 2126)
+
+        Performance and stability improvements on all platforms.
+
+
+2012-05-11: Version 3.11.0
+
+        Fixed compose-discard crasher from r11524 (issue 2123).
+
+        Activated new global semantics by default. Global variables can
+        now shadow properties of the global object (ES5.1 erratum).
+
+        Properly set ElementsKind of empty FAST_DOUBLE_ELEMENTS arrays when
+        transitioning (Chromium issue 117409).
+
+        Made Error.prototype.name writable again, as required by the spec and
+        the web (Chromium issue 69187).
+
+        Implemented map collection with incremental marking (issue 1465).
+
+        Regexp: Fixed overflow in min-match-length calculation
+        (Chromium issue 126412).
+
+        MIPS: Fixed illegal instruction use on Loongson in code for
+        Math.random() (issue 2115).
+
+        Fixed crash bug in VisitChoice (Chromium issue 126272).
+
+        Fixed unsigned-Smi check in MappedArgumentsLookup
+        (Chromium issue 126414).
+
+        Fixed LiveEdit for function with no locals (issue 825).
+
+        Fixed register clobbering in LoadIC for interceptors
+        (Chromium issue 125988).
+
+        Implemented clearing of CompareICs (issue 2102).
+
+        Performance and stability improvements on all platforms.
+
+
+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/DEPS b/deps/v8/DEPS
new file mode 100644 (file)
index 0000000..e50d1d2
--- /dev/null
@@ -0,0 +1,27 @@
+# Note: The buildbots evaluate this file with CWD set to the parent
+# directory and assume that the root of the checkout is in ./v8/, so
+# all paths in here must match this assumption.
+
+deps = {
+  # Remember to keep the revision in sync with the Makefile.
+  "v8/build/gyp":
+    "http://gyp.googlecode.com/svn/trunk@1282",
+}
+
+deps_os = {
+  "win": {
+    "v8/third_party/cygwin":
+      "http://src.chromium.org/svn/trunk/deps/third_party/cygwin@66844",
+
+    "v8/third_party/python_26":
+      "http://src.chromium.org/svn/trunk/tools/third_party/python_26@89111",
+  }
+}
+
+hooks = [
+  {
+    # A change to a .gyp, .gypi, or to GYP itself should run the generator.
+    "pattern": ".",
+    "action": ["python", "v8/build/gyp_v8"],
+  },
+]
index 5dc6ca5..fbca566 100644 (file)
@@ -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,55 +197,40 @@ native.check: native
            --arch-and-mode=. $(TESTFLAGS)
 
 # Clean targets. You can clean each architecture individually, or everything.
-$(addsuffix .clean,$(ARCHES)):
-       rm -f $(OUTDIR)/Makefile-$(basename $@)
+$(addsuffix .clean,$(ARCHES)) android.clean:
+       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
-
-android.clean:
-       rm -f $(OUTDIR)/Makefile-android
-       rm -rf $(OUTDIR)/android.release
-       find $(OUTDIR) -regex '.*\(host\|target\)-android\.mk' -delete
+       find $(OUTDIR) -regex '.*\(host\|target\).native\.mk' -delete
 
-clean: $(addsuffix .clean,$(ARCHES)) native.clean
+clean: $(addsuffix .clean,$(ARCHES)) native.clean android.clean
 
 # GYP file generation targets.
-$(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
+MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ARCHES))
+$(MAKEFILES): $(GYPFILES) $(ENVFILE)
+       GYP_GENERATORS=make \
        build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
-                     -Ibuild/standalone.gypi --depth=. -Ibuild/mipsu.gypi \
-                     -S-mips $(GYPFLAGS)
+                     -Ibuild/standalone.gypi --depth=. \
+                     -Dv8_target_arch=$(subst .,,$(suffix $@)) \
+                     -S.$(subst .,,$(suffix $@)) $(GYPFLAGS)
 
-$(OUTDIR)/Makefile-native: $(GYPFILES) $(ENVFILE)
+$(OUTDIR)/Makefile.native: $(GYPFILES) $(ENVFILE)
+       GYP_GENERATORS=make \
        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
@@ -255,9 +246,10 @@ $(ENVFILE): $(ENVFILE).new
 
 # Stores current GYPFLAGS in a file.
 $(ENVFILE).new:
-       @mkdir -p $(OUTDIR); echo "GYPFLAGS=$(GYPFLAGS)" > $(ENVFILE).new;
+       @mkdir -p $(OUTDIR); echo "GYPFLAGS=$(GYPFLAGS)" > $(ENVFILE).new; \
+           echo "CXX=$(CXX)" >> $(ENVFILE).new
 
 # Dependencies.
 dependencies:
        svn checkout --force http://gyp.googlecode.com/svn/trunk build/gyp \
-           --revision 1026
+           --revision 1282
index 34d0efc..b0d1344 100644 (file)
@@ -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
deleted file mode 100644 (file)
index d15b8ab..0000000
+++ /dev/null
@@ -1,36 +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.
-
-{
-  'variables': {
-    'target_arch': 'ia32',
-    'v8_target_arch': 'arm',
-    'armv7': 1,
-    'arm_neon': 0,
-    'arm_fpu': 'vfpv3',
-  },
-}
index f2bb465..4a9d45d 100644 (file)
                   'USE_EABI_HARDFLOAT=1',
                   'CAN_USE_VFP_INSTRUCTIONS',
                 ],
-                'cflags': [
-                  '-mfloat-abi=hard',
+                'target_conditions': [
+                  ['_toolset=="target"', {
+                    'cflags': ['-mfloat-abi=hard',],
+                  }],
                 ],
               }, {
                 'defines': [
             'defines': [
               'V8_TARGET_ARCH_MIPS',
             ],
+            'variables': {
+              'mipscompiler': '<!($(echo ${CXX:-$(which g++)}) -v 2>&1 | grep -q "^Target: mips-" && echo "yes" || echo "no")',
+            },
             'conditions': [
-              [ 'target_arch=="mips"', {
+              ['mipscompiler=="yes"', {
                 'target_conditions': [
                   ['_toolset=="target"', {
                     'cflags': ['-EL'],
             ],
           }],
         ],
+      }, {  # 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': [
           },
         },
       }],
+      ['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': [
-          [ 'target_arch=="ia32"', {
-            'cflags': [ '-m32' ],
-            'ldflags': [ '-m32' ],
+          [ '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 -n "-m32" || true)',
+            },
+            'cflags': [ '<(m32flag)' ],
+            'ldflags': [ '<(m32flag)' ],
           }],
           [ 'v8_no_strict_aliasing==1', {
             'cflags': [ '-fno-strict-aliasing' ],
           },
           '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': [
             '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' ],
           }],
         ],
           }],  # OS=="mac"
           ['OS=="win"', {
             'msvs_configuration_attributes': {
+              'OutputDirectory': '<(DEPTH)\\build\\$(ConfigurationName)',
               'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
               'CharacterSet': '1',
             },
               '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"
index 4293e76..345f777 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 #
-# Copyright 2010 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:
@@ -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,23 +164,6 @@ if __name__ == '__main__':
 
   # Generate for the architectures supported on the given platform.
   gyp_args = list(args)
-  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('-I' + v8_root + '/build/armu.gypi')
-    gyp_args.append('-S-armu')
-    run_gyp(gyp_args)
-
-    gyp_args = list(args)
-    gyp_args.append('-I' + v8_root + '/build/mipsu.gypi')
-    gyp_args.append('-S-mipsu')
-    run_gyp(gyp_args)
diff --git a/deps/v8/build/mipsu.gypi b/deps/v8/build/mipsu.gypi
deleted file mode 100644 (file)
index 637ff84..0000000
+++ /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.
-
-{
-  'variables': {
-    'target_arch': 'ia32',
-    'v8_target_arch': 'mips',
-  },
-}
index e9b0565..ebdf557 100644 (file)
@@ -37,8 +37,9 @@
       'variables': {
         'variables': {
           'conditions': [
-            ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
-              # This handles the Linux platforms we generally deal with.
+            ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or \
+               OS=="netbsd" or OS=="mac"', {
+              # This handles the Unix platforms we generally deal with.
               # Anything else gets passed through, which probably won't work
               # very well; such hosts should pass an explicit target_arch
               # to gyp.
@@ -46,7 +47,8 @@
                 '<!(uname -m | sed -e "s/i.86/ia32/;\
                   s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
             }, {
-              # OS!="linux" and OS!="freebsd" and OS!="openbsd" and OS!="netbsd"
+              # OS!="linux" and OS!="freebsd" and OS!="openbsd" and
+              # OS!="netbsd" and OS!="mac"
               'host_arch%': 'ia32',
             }],
           ],
         'want_separate_host_toolset': 0,
       }],
     ],
+    # Default ARM variable settings.
+    'armv7%': 1,
+    'arm_neon%': 0,
+    'arm_fpu%': 'vfpv3',
   },
   'target_defaults': {
     'default_configuration': 'Debug',
       },
     }],  # OS=="win"
     ['OS=="mac"', {
+      'xcode_settings': {
+        'SYMROOT': '<(DEPTH)/xcodebuild',
+      },
       'target_defaults': {
         'xcode_settings': {
           'ALWAYS_SEARCH_USER_PATHS': 'NO',
           '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',
index 2499bbf..8f380f2 100644 (file)
@@ -64,6 +64,7 @@
  */
 namespace v8 {
 
+typedef uint32_t SnapshotObjectId;
 
 /**
  * CpuProfileNode represents a node in a call graph.
@@ -274,7 +275,7 @@ class V8EXPORT HeapGraphNode {
    * Returns node id. For the same heap object, the id remains the same
    * across all snapshots.
    */
-  uint64_t GetId() const;
+  SnapshotObjectId GetId() const;
 
   /** Returns node's own size, in bytes. */
   int GetSelfSize() const;
@@ -338,7 +339,7 @@ class V8EXPORT HeapSnapshot {
   const HeapGraphNode* GetRoot() const;
 
   /** Returns a node by its id. */
-  const HeapGraphNode* GetNodeById(uint64_t id) const;
+  const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
 
   /** Returns total nodes count in the snapshot. */
   int GetNodesCount() const;
@@ -346,6 +347,9 @@ 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
@@ -364,16 +368,20 @@ class V8EXPORT HeapSnapshot {
    * with the following structure:
    *
    *  {
-   *    snapshot: {title: "...", uid: nnn},
-   *    nodes: [
-   *      meta-info (JSON string),
-   *      nodes themselves
-   *    ],
-   *    strings: [strings]
+   *    snapshot: {
+   *      title: "...",
+   *      uid: nnn,
+   *      meta: { meta-info },
+   *      node_count: nnn,
+   *      edge_count: nnn
+   *    },
+   *    nodes: [nodes array],
+   *    edges: [edges array],
+   *    strings: [strings array]
    *  }
    *
-   * Outgoing node links are stored after each node. Nodes reference strings
-   * and other nodes by their indexes in corresponding arrays.
+   * Nodes reference strings, other nodes, and edges by their indexes
+   * in corresponding arrays.
    */
   void Serialize(OutputStream* stream, SerializationFormat format) const;
 };
@@ -405,6 +413,19 @@ 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.
    */
@@ -414,6 +435,33 @@ 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.
    */
@@ -510,6 +558,19 @@ 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
 
 
index 33179f5..9024531 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -107,6 +107,7 @@ class Data;
 class AccessorInfo;
 class StackTrace;
 class StackFrame;
+class Isolate;
 
 namespace internal {
 
@@ -862,13 +863,13 @@ class Value : public Data {
    * Returns true if this value is the undefined value.  See ECMA-262
    * 4.3.10.
    */
-  V8EXPORT bool IsUndefined() const;
+  inline bool IsUndefined() const;
 
   /**
    * Returns true if this value is the null value.  See ECMA-262
    * 4.3.11.
    */
-  V8EXPORT bool IsNull() const;
+  inline bool IsNull() const;
 
    /**
    * Returns true if this value is true.
@@ -982,7 +983,11 @@ 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;
 };
 
@@ -1079,6 +1084,7 @@ 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
@@ -1236,8 +1242,7 @@ 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);
 
   /**
@@ -1968,10 +1973,13 @@ class Arguments {
   inline Local<Object> Holder() const;
   inline bool IsConstructCall() const;
   inline Local<Value> Data() const;
+  inline Isolate* GetIsolate() const;
+
  private:
-  static const int kDataIndex = 0;
-  static const int kCalleeIndex = -1;
-  static const int kHolderIndex = -2;
+  static const int kIsolateIndex = 0;
+  static const int kDataIndex = -1;
+  static const int kCalleeIndex = -2;
+  static const int kHolderIndex = -3;
 
   friend class ImplementationUtilities;
   inline Arguments(internal::Object** implicit_args,
@@ -1993,9 +2001,11 @@ 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_;
 };
@@ -2552,6 +2562,11 @@ 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.
@@ -2802,13 +2817,13 @@ class V8EXPORT Isolate {
   /**
    * Associate embedder-specific data with the isolate
    */
-  void SetData(void* data);
+  inline void SetData(void* data);
 
   /**
-   * Retrive embedder-specific data from the isolate.
+   * Retrieve embedder-specific data from the isolate.
    * Returns NULL if SetData has never been called.
    */
-  void* GetData();
+  inline void* GetData();
 
  private:
   Isolate();
@@ -3153,7 +3168,8 @@ class V8EXPORT V8 {
    *   that is kept alive by JavaScript objects.
    * \returns the adjusted value.
    */
-  static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
+  static intptr_t AdjustAmountOfExternalAllocatedMemory(
+      intptr_t change_in_bytes);
 
   /**
    * Suspends recording of tick samples in the profiler.
@@ -3736,6 +3752,12 @@ 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
@@ -3760,6 +3782,14 @@ 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;
+  };
 };
 
 
@@ -3848,18 +3878,6 @@ 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
@@ -3871,18 +3889,31 @@ class Internals {
   // the implementation of v8.
   static const int kHeapObjectMapOffset = 0;
   static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize;
-  static const int kStringResourceOffset =
-      InternalConstants<kApiPointerSize>::kStringResourceOffset;
+  static const int kStringResourceOffset = 3 * kApiPointerSize;
 
+  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);
@@ -3902,6 +3933,11 @@ 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);
@@ -3922,6 +3958,28 @@ 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;
@@ -4048,6 +4106,11 @@ Local<Value> Arguments::Data() const {
 }
 
 
+Isolate* Arguments::GetIsolate() const {
+  return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]);
+}
+
+
 bool Arguments::IsConstructCall() const {
   return is_construct_call_;
 }
@@ -4160,6 +4223,15 @@ 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;
@@ -4178,6 +4250,42 @@ 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();
@@ -4283,6 +4391,11 @@ 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]));
 }
@@ -4298,6 +4411,54 @@ 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
index 1606a8f..7a84a2a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2009 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:
@@ -434,9 +434,9 @@ v8::Handle<v8::String> ReadLine() {
   }
   if (res == NULL) {
     v8::Handle<v8::Primitive> t = v8::Undefined();
-    return reinterpret_cast<v8::Handle<v8::String>&>(t);
+    return v8::Handle<v8::String>(v8::String::Cast(*t));
   }
-  // remove newline char
+  // Remove newline char
   for (char* pos = buffer; *pos != '\0'; pos++) {
     if (*pos == '\n') {
       *pos = '\0';
index 55b2a98..3c720a7 100644 (file)
@@ -1,4 +1,4 @@
-# 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:
       'sources': [
         'process.cc',
       ],
+    },
+    {
+      'target_name': 'lineprocessor',
+      'sources': [
+        'lineprocessor.cc',
+      ],
     }
   ],
 }
index b40eca2..db0cc1a 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -67,17 +67,20 @@ static bool run_shell;
 int main(int argc, char* argv[]) {
   v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
   run_shell = (argc == 1);
-  v8::HandleScope handle_scope;
-  v8::Persistent<v8::Context> context = CreateShellContext();
-  if (context.IsEmpty()) {
-    printf("Error creating context\n");
-    return 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();
   }
-  context->Enter();
-  int result = RunMain(argc, argv);
-  if (run_shell) RunShell(context);
-  context->Exit();
-  context.Dispose();
   v8::V8::Dispose();
   return result;
 }
index 49a026b..52a84ed 100644 (file)
@@ -512,6 +512,16 @@ 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);
@@ -2091,17 +2101,21 @@ bool StackFrame::IsConstructor() const {
 
 // --- D a t a ---
 
-bool Value::IsUndefined() const {
+bool Value::FullIsUndefined() const {
   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) {
     return false;
   }
-  return Utils::OpenHandle(this)->IsUndefined();
+  bool result = Utils::OpenHandle(this)->IsUndefined();
+  ASSERT_EQ(result, QuickIsUndefined());
+  return result;
 }
 
 
-bool Value::IsNull() const {
+bool Value::FullIsNull() const {
   if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false;
-  return Utils::OpenHandle(this)->IsNull();
+  bool result = Utils::OpenHandle(this)->IsNull();
+  ASSERT_EQ(result, QuickIsNull());
+  return result;
 }
 
 
@@ -2799,9 +2813,13 @@ 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 turning on access checks for a global object deoptimize all functions
-  // as optimized code does not always handle access checks.
-  i::Deoptimizer::DeoptimizeGlobalObject(*self);
+  // 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();
+  }
 
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
@@ -4170,7 +4188,7 @@ void v8::Object::SetPointerInInternalField(int index, void* value) {
 
 
 bool v8::V8::Initialize() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   if (isolate != NULL && isolate->IsInitialized()) {
     return true;
   }
@@ -4277,6 +4295,7 @@ Persistent<Context> v8::Context::New(
     v8::ExtensionConfiguration* extensions,
     v8::Handle<ObjectTemplate> global_template,
     v8::Handle<Value> global_object) {
+  i::Isolate::EnsureDefaultIsolate();
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Context::New()");
   LOG_API(isolate, "Context::New");
@@ -4611,7 +4630,9 @@ void* External::Value() const {
 
 Local<String> v8::String::Empty() {
   i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::String::Empty()");
+  if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) {
+    return v8::Local<String>();
+  }
   LOG_API(isolate, "String::Empty()");
   return Utils::ToLocal(isolate->factory()->empty_symbol());
 }
@@ -5063,7 +5084,7 @@ Local<Number> v8::Number::New(double value) {
 
 
 Local<Integer> v8::Integer::New(int32_t value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
   if (i::Smi::IsValid(value)) {
     return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
@@ -5197,7 +5218,7 @@ void V8::AddImplicitReferences(Persistent<Object> parent,
 }
 
 
-int V8::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
+intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
     return 0;
@@ -5269,6 +5290,7 @@ void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
 
 void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
   if (callback == NULL) return;
+  i::Isolate::EnsureDefaultIsolate();
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::AddLeaveScriptCallback()")) return;
   i::V8::AddCallCompletedCallback(callback);
@@ -5276,6 +5298,7 @@ void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
 
 
 void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
+  i::Isolate::EnsureDefaultIsolate();
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::V8::RemoveLeaveScriptCallback()")) return;
   i::V8::RemoveCallCompletedCallback(callback);
@@ -5341,7 +5364,7 @@ bool V8::IsExecutionTerminating(Isolate* isolate) {
 
 
 Isolate* Isolate::GetCurrent() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   return reinterpret_cast<Isolate*>(isolate);
 }
 
@@ -5375,17 +5398,6 @@ 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();
@@ -5985,7 +5997,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);
 }
 
@@ -6019,7 +6031,7 @@ Handle<String> HeapGraphNode::GetName() const {
 }
 
 
-uint64_t HeapGraphNode::GetId() const {
+SnapshotObjectId HeapGraphNode::GetId() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
   return ToInternal(this)->id();
@@ -6051,7 +6063,7 @@ const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
   return reinterpret_cast<const HeapGraphEdge*>(
-      &ToInternal(this)->children()[index]);
+      ToInternal(this)->children()[index]);
 }
 
 
@@ -6134,18 +6146,18 @@ const HeapGraphNode* HeapSnapshot::GetRoot() const {
 }
 
 
-const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
+const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
   return reinterpret_cast<const HeapGraphNode*>(
-      ToInternal(this)->GetEntryById(static_cast<i::SnapshotObjectId>(id)));
+      ToInternal(this)->GetEntryById(id));
 }
 
 
 int HeapSnapshot::GetNodesCount() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
-  return ToInternal(this)->entries()->length();
+  return ToInternal(this)->entries().length();
 }
 
 
@@ -6153,7 +6165,14 @@ const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
   return reinterpret_cast<const HeapGraphNode*>(
-      ToInternal(this)->entries()->at(index));
+      &ToInternal(this)->entries().at(index));
+}
+
+
+SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
+  i::Isolate* isolate = i::Isolate::Current();
+  IsDeadCheck(isolate, "v8::HeapSnapshot::GetMaxSnapshotJSObjectId");
+  return ToInternal(this)->max_snapshot_js_object_id();
 }
 
 
@@ -6198,6 +6217,14 @@ 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) {
@@ -6217,6 +6244,27 @@ 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");
@@ -6264,7 +6312,11 @@ static void SetFlagsFromString(const char* flags) {
 
 void Testing::PrepareStressRun(int run) {
   static const char* kLazyOptimizations =
-      "--prepare-always-opt --nolimit-inlining --noalways-opt";
+      "--prepare-always-opt "
+      "--max-inlined-source-size=999999 "
+      "--max-inlined-nodes=999999 "
+      "--max-inlined-nodes-cumulative=999999 "
+      "--noalways-opt";
   static const char* kForcedOptimizations = "--always-opt";
 
   // If deoptimization stressed turn on frequent deoptimization. If no value
index 89cf0c8..3ad57f4 100644 (file)
@@ -146,6 +146,7 @@ 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_; }
index 68579af..71c0e1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2009 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:
@@ -40,14 +40,17 @@ class ImplementationUtilities {
   }
 
   // Packs additional parameters for the NewArguments function. |implicit_args|
-  // is a pointer to the last element of 3-elements array controlled by GC.
+  // is a pointer to the last element of 4-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,
@@ -55,6 +58,8 @@ 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);
   }
index e9a3270..f8fb00c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 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:
@@ -91,9 +91,11 @@ class CustomArguments : public Relocatable {
                          Object* data,
                          Object* self,
                          JSObject* holder) : Relocatable(isolate) {
-    values_[2] = self;
-    values_[1] = holder;
-    values_[0] = data;
+    ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi());
+    values_[3] = self;
+    values_[2] = holder;
+    values_[1] = data;
+    values_[0] = reinterpret_cast<Object*>(isolate);
   }
 
   inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) {
@@ -106,8 +108,9 @@ class CustomArguments : public Relocatable {
 
   void IterateInstance(ObjectVisitor* v);
   Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
+
  private:
-  Object* values_[3];
+  Object* values_[4];
 };
 
 
index f772db9..ad2ab7e 100644 (file)
@@ -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(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
-    __ str(r2, MemOperand(sp, argc_ * kPointerSize));
+    __ ldr(r3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+    __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset));
+    __ str(r3, MemOperand(sp, argc_ * kPointerSize));
     __ bind(&call);
   }
 
@@ -5179,9 +5179,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
   // r1: pushed function (to be verified)
   __ JumpIfSmi(r1, &non_function);
   // Get the map of the function object.
-  __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
+  __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
   __ b(ne, &slow);
 
+  if (RecordCallTarget()) {
+    GenerateRecordCallTarget(masm);
+  }
+
   // Fast-case: Invoke the function now.
   // r1: pushed function
   ParameterCount actual(argc_);
@@ -5205,8 +5209,17 @@ 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(r2, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
   __ b(ne, &non_function);
   __ push(r1);  // put proxy as additional argument
   __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE));
@@ -5873,36 +5886,12 @@ 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
index 96139a2..3e7a1e9 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -125,6 +125,8 @@ void BreakLocationIterator::ClearDebugBreakAtSlot() {
                      Assembler::kDebugBreakSlotInstructions);
 }
 
+const bool Debug::FramePaddingLayout::kIsSupported = false;
+
 
 #define __ ACCESS_MASM(masm)
 
index 7b2a3c4..699e6aa 100644 (file)
@@ -457,6 +457,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -464,7 +466,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 7 * kPointerSize;
+  unsigned fixed_frame_size = 8 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -529,6 +531,15 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -559,8 +570,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
index 0cbd46e..9f44872 100644 (file)
@@ -70,6 +70,7 @@ class JumpPatchSite BASE_EMBEDDED {
   // the inlined smi code.
   void EmitJumpIfNotSmi(Register reg, Label* target) {
     ASSERT(!patch_site_.is_bound() && !info_emitted_);
+    Assembler::BlockConstPoolScope block_const_pool(masm_);
     __ bind(&patch_site_);
     __ cmp(reg, Operand(reg));
     // Don't use b(al, ...) as that might emit the constant pool right after the
@@ -82,6 +83,7 @@ class JumpPatchSite BASE_EMBEDDED {
   // the inlined smi code.
   void EmitJumpIfSmi(Register reg, Label* target) {
     ASSERT(!patch_site_.is_bound() && !info_emitted_);
+    Assembler::BlockConstPoolScope block_const_pool(masm_);
     __ bind(&patch_site_);
     __ cmp(reg, Operand(reg));
     __ b(ne, target);  // Never taken before patched.
@@ -110,13 +112,6 @@ 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
@@ -273,11 +268,11 @@ void FullCodeGenerator::Generate() {
       // For named function expressions, declare the function name as a
       // constant.
       if (scope()->is_function_scope() && scope()->function() != NULL) {
-        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);
+        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);
       }
       VisitDeclarations(scope()->declarations());
     }
@@ -787,62 +782,51 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
 }
 
 
-void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
-                                        VariableMode mode,
-                                        FunctionLiteral* function) {
+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) {
   // 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 binding_needs_init = (function == NULL) &&
-      (mode == CONST || mode == CONST_HARMONY || mode == LET);
+  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_->Add(variable->name());
+      globals_->Add(variable->binding_needs_init()
+                        ? isolate()->factory()->the_hole_value()
+                        : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
     case Variable::LOCAL:
-      if (function != NULL) {
-        Comment cmnt(masm_, "[ Declaration");
-        VisitForAccumulatorValue(function);
-        __ str(result_register(), StackOperand(variable));
-      } else if (binding_needs_init) {
-        Comment cmnt(masm_, "[ Declaration");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
         __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
         __ str(ip, StackOperand(variable));
       }
       break;
 
     case Variable::CONTEXT:
-      // 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");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        EmitDebugCheckDeclarationContext(variable);
         __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
         __ str(ip, ContextOperand(cp, variable->index()));
         // No write barrier since the_hole_value is in old space.
@@ -851,13 +835,11 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       break;
 
     case Variable::LOOKUP: {
-      Comment cmnt(masm_, "[ Declaration");
+      Comment cmnt(masm_, "[ VariableDeclaration");
       __ mov(r2, Operand(variable->name()));
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR ||
-             mode == CONST ||
-             mode == CONST_HARMONY ||
-             mode == LET);
+      ASSERT(mode == VAR || mode == LET ||
+             mode == CONST || mode == CONST_HARMONY);
       PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
           ? READ_ONLY : NONE;
       __ mov(r1, Operand(Smi::FromInt(attr)));
@@ -865,11 +847,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       // 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 (function != NULL) {
-        __ Push(cp, r2, r1);
-        // Push initial value for function declaration.
-        VisitForStackValue(function);
-      } else if (binding_needs_init) {
+      if (hole_init) {
         __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
         __ Push(cp, r2, r1, r0);
       } else {
@@ -883,6 +861,122 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
 }
 
 
+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.
@@ -2269,6 +2363,18 @@ 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);
@@ -3660,7 +3766,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));
+  __ add(string_length, string_length, Operand(scratch1), SetCC);
   __ b(vs, &bailout);
   __ cmp(element, elements_end);
   __ b(lt, &loop);
@@ -3697,7 +3803,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   __ b(ne, &bailout);
   __ tst(scratch2, Operand(0x80000000));
   __ b(ne, &bailout);
-  __ add(string_length, string_length, Operand(scratch2));
+  __ add(string_length, string_length, Operand(scratch2), SetCC);
   __ b(vs, &bailout);
   __ SmiUntag(string_length);
 
@@ -4453,7 +4559,8 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope()) {
+  if (declaration_scope->is_global_scope() ||
+      declaration_scope->is_module_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
index e843657..c12c167 100644 (file)
@@ -774,7 +774,7 @@ static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
   __ b(lt, slow_case);
 
   // Check that the key is a positive smi.
-  __ tst(key, Operand(0x8000001));
+  __ tst(key, Operand(0x80000001));
   __ b(ne, slow_case);
 
   // Load the elements into scratch1 and check its map.
@@ -1690,12 +1690,12 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
 
   // Activate inlined smi code.
   if (previous_state == UNINITIALIZED) {
-    PatchInlinedSmiCode(address());
+    PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
   }
 }
 
 
-void PatchInlinedSmiCode(Address address) {
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
   Address cmp_instruction_address =
       address + Assembler::kCallTargetAddressOffset;
 
@@ -1729,34 +1729,31 @@ void PatchInlinedSmiCode(Address address) {
   Instr instr_at_patch = Assembler::instr_at(patch_address);
   Instr branch_instr =
       Assembler::instr_at(patch_address + Instruction::kInstrSize);
-  ASSERT(Assembler::IsCmpRegister(instr_at_patch));
-  ASSERT_EQ(Assembler::GetRn(instr_at_patch).code(),
-            Assembler::GetRm(instr_at_patch).code());
+  // This is patching a conditional "jump if not smi/jump if smi" site.
+  // Enabling by changing from
+  //   cmp rx, rx
+  //   b eq/ne, <target>
+  // to
+  //   tst rx, #kSmiTagMask
+  //   b ne/eq, <target>
+  // and vice-versa to be disabled again.
+  CodePatcher patcher(patch_address, 2);
+  Register reg = Assembler::GetRn(instr_at_patch);
+  if (check == ENABLE_INLINED_SMI_CHECK) {
+    ASSERT(Assembler::IsCmpRegister(instr_at_patch));
+    ASSERT_EQ(Assembler::GetRn(instr_at_patch).code(),
+              Assembler::GetRm(instr_at_patch).code());
+    patcher.masm()->tst(reg, Operand(kSmiTagMask));
+  } else {
+    ASSERT(check == DISABLE_INLINED_SMI_CHECK);
+    ASSERT(Assembler::IsTstImmediate(instr_at_patch));
+    patcher.masm()->cmp(reg, reg);
+  }
   ASSERT(Assembler::IsBranch(branch_instr));
   if (Assembler::GetCondition(branch_instr) == eq) {
-    // This is patching a "jump if not smi" site to be active.
-    // Changing
-    //   cmp rx, rx
-    //   b eq, <target>
-    // to
-    //   tst rx, #kSmiTagMask
-    //   b ne, <target>
-    CodePatcher patcher(patch_address, 2);
-    Register reg = Assembler::GetRn(instr_at_patch);
-    patcher.masm()->tst(reg, Operand(kSmiTagMask));
     patcher.EmitCondition(ne);
   } else {
     ASSERT(Assembler::GetCondition(branch_instr) == ne);
-    // This is patching a "jump if smi" site to be active.
-    // Changing
-    //   cmp rx, rx
-    //   b ne, <target>
-    // to
-    //   tst rx, #kSmiTagMask
-    //   b eq, <target>
-    CodePatcher patcher(patch_address, 2);
-    Register reg = Assembler::GetRn(instr_at_patch);
-    patcher.masm()->tst(reg, Operand(kSmiTagMask));
     patcher.EmitCondition(eq);
   }
 }
index cdc1947..5c60f53 100644 (file)
@@ -108,22 +108,17 @@ void LInstruction::PrintTo(StringStream* stream) {
 }
 
 
-template<int R, int I, int T>
-void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
+void LInstruction::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  for (int i = 0; i < inputs_.length(); i++) {
+  for (int i = 0; i < InputCount(); i++) {
     if (i > 0) stream->Add(" ");
-    inputs_[i]->PrintTo(stream);
+    InputAt(i)->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);
-  }
+void LInstruction::PrintOutputOperandTo(StringStream* stream) {
+  if (HasResult()) result()->PrintTo(stream);
 }
 
 
@@ -732,22 +727,6 @@ 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) {
@@ -760,8 +739,10 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
   if (hinstr->HasObservableSideEffects()) {
     ASSERT(hinstr->next()->IsSimulate());
     HSimulate* sim = HSimulate::cast(hinstr->next());
-    instr = SetInstructionPendingDeoptimizationEnvironment(
-        instr, sim->ast_id());
+    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();
   }
 
   // If instruction does not have side-effects lazy deoptimization
@@ -779,12 +760,6 @@ 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_));
@@ -1295,6 +1270,7 @@ 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));
 }
@@ -1319,6 +1295,75 @@ 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());
@@ -1753,9 +1798,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
+LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  LInstruction* result = new(zone()) LCheckMap(value);
+  LInstruction* result = new(zone()) LCheckMaps(value);
   return AssignEnvironment(result);
 }
 
@@ -2242,9 +2287,12 @@ 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_->
-        set_deoptimization_environment(result->environment());
-    ClearInstructionPendingDeoptimizationEnvironment();
+        SetDeferredLazyDeoptimizationEnvironment(result->environment());
+    instruction_pending_deoptimization_environment_ = NULL;
+    pending_deoptimization_ast_id_ = AstNode::kNoNumber;
     return result;
   }
 
@@ -2271,6 +2319,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
                                                undefined,
                                                instr->call_kind(),
                                                instr->is_construct());
+  if (instr->arguments_var() != NULL) {
+    inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
+  }
   current_block_->UpdateEnvironment(inner);
   chunk_->AddInlinedClosure(instr->closure());
   return NULL;
@@ -2278,10 +2329,21 @@ 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 NULL;
+
+  return pop;
 }
 
 
index 62cde6e..ec8aac8 100644 (file)
@@ -72,7 +72,7 @@ class LCodeGen;
   V(CheckFunction)                              \
   V(CheckInstanceType)                          \
   V(CheckNonSmi)                                \
-  V(CheckMap                                  \
+  V(CheckMaps)                                  \
   V(CheckPrototypeMaps)                         \
   V(CheckSmi)                                   \
   V(ClampDToUint8)                              \
@@ -132,6 +132,7 @@ class LCodeGen;
   V(LoadNamedField)                             \
   V(LoadNamedFieldPolymorphic)                  \
   V(LoadNamedGeneric)                           \
+  V(MathFloorOfDiv)                             \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -179,7 +180,8 @@ class LCodeGen;
   V(CheckMapValue)                              \
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
-  V(WrapReceiver)
+  V(WrapReceiver)                               \
+  V(Drop)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -203,15 +205,14 @@ class LInstruction: public ZoneObject {
   LInstruction()
       :  environment_(NULL),
          hydrogen_value_(NULL),
-         is_call_(false),
-         is_save_doubles_(false) { }
+         is_call_(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) = 0;
-  virtual void PrintOutputOperandTo(StringStream* stream) = 0;
+  virtual void PrintDataTo(StringStream* stream);
+  virtual void PrintOutputOperandTo(StringStream* stream);
 
   enum Opcode {
     // Declare a unique enum value for each instruction.
@@ -246,22 +247,12 @@ class LInstruction: public ZoneObject {
   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
 
-  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;
@@ -282,9 +273,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_;
 };
 
 
@@ -306,9 +295,6 @@ 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_;
@@ -534,9 +520,8 @@ 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)
 };
 
 
@@ -582,6 +567,21 @@ 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,6 +834,15 @@ 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_;
 };
 
 
@@ -1378,6 +1387,19 @@ 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")
@@ -1460,6 +1482,7 @@ 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(); }
 };
 
 
@@ -1739,6 +1762,8 @@ 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(); }
 };
 
 
@@ -1889,14 +1914,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
 };
 
 
-class LCheckMap: public LTemplateInstruction<0, 1, 0> {
+class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckMap(LOperand* value) {
+  explicit LCheckMaps(LOperand* value) {
     inputs_[0] = value;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
-  DECLARE_HYDROGEN_ACCESSOR(CheckMap)
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
+  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
 };
 
 
@@ -2274,6 +2299,10 @@ 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,
@@ -2369,11 +2398,6 @@ 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);
index 82b80a2..bf11ab9 100644 (file)
@@ -1034,6 +1034,100 @@ 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:
@@ -1115,6 +1209,34 @@ 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) {
@@ -2267,8 +2389,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                   RelocInfo::CODE_TARGET,
                   instr,
                   RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
-  ASSERT(instr->HasDeoptimizationEnvironment());
-  LEnvironment* env = instr->deoptimization_environment();
+  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
   safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
   // Put the result value into the result register slot and
   // restore all registers.
@@ -2466,42 +2587,38 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
   Register object = ToRegister(instr->object());
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
+
   int map_count = instr->hydrogen()->types()->length();
+  bool need_generic = instr->hydrogen()->need_generic();
+
+  if (map_count == 0 && !need_generic) {
+    DeoptimizeIf(al, instr->environment());
+    return;
+  }
   Handle<String> name = instr->hydrogen()->name();
-  if (map_count == 0) {
-    ASSERT(instr->hydrogen()->need_generic());
-    __ mov(r2, Operand(name));
-    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  } else {
-    Label done;
-    __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
-    for (int i = 0; i < map_count - 1; ++i) {
-      Handle<Map> map = instr->hydrogen()->types()->at(i);
+  Label done;
+  __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  for (int i = 0; i < map_count; ++i) {
+    bool last = (i == map_count - 1);
+    Handle<Map> map = instr->hydrogen()->types()->at(i);
+    __ cmp(scratch, Operand(map));
+    if (last && !need_generic) {
+      DeoptimizeIf(ne, instr->environment());
+      EmitLoadFieldOrConstantFunction(result, object, map, name);
+    } else {
       Label next;
-      __ cmp(scratch, Operand(map));
       __ b(ne, &next);
       EmitLoadFieldOrConstantFunction(result, object, map, name);
       __ b(&done);
       __ bind(&next);
     }
-    Handle<Map> map = instr->hydrogen()->types()->last();
-    __ cmp(scratch, Operand(map));
-    if (instr->hydrogen()->need_generic()) {
-      Label generic;
-      __ b(ne, &generic);
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-      __ b(&done);
-      __ bind(&generic);
-      __ mov(r2, Operand(name));
-      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      CallCode(ic, RelocInfo::CODE_TARGET, instr);
-    } else {
-      DeoptimizeIf(ne, instr->environment());
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-    }
-    __ bind(&done);
   }
+  if (need_generic) {
+    __ mov(r2, Operand(name));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  }
+  __ bind(&done);
 }
 
 
@@ -2764,16 +2881,20 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
   Register scratch = scratch0();
   Register result = ToRegister(instr->result());
 
-  // 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)));
+  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)));
 
-  // 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);
+  }
 }
 
 
@@ -2882,7 +3003,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
   __ b(ne, &loop);
 
   __ bind(&invoke);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -2907,6 +3028,11 @@ 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());
@@ -2953,7 +3079,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 R1State r1_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;
 
@@ -2961,7 +3088,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
   RecordPosition(pointers->position());
 
   if (can_invoke_directly) {
-    __ LoadHeapObject(r1, function);
+    if (r1_state == R1_UNINITIALIZED) {
+      __ LoadHeapObject(r1, function);
+    }
+
     // Change context if needed.
     bool change_context =
         (info()->closure()->context() != function->context()) ||
@@ -3000,7 +3130,8 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    R1_UNINITIALIZED);
 }
 
 
@@ -3424,13 +3555,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
   ASSERT(ToRegister(instr->function()).is(r1));
   ASSERT(instr->HasPointerMap());
-  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));
+
+  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);
+  }
 }
 
 
@@ -3485,7 +3624,11 @@ 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);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    R1_UNINITIALIZED);
 }
 
 
@@ -3615,7 +3758,6 @@ 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.
@@ -3638,13 +3780,15 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
            Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
   }
 
-  // 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);
+  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);
+  }
 
-  __ bind(&not_nan);
   __ vstr(value, scratch, 0);
 }
 
@@ -4338,14 +4482,22 @@ void LCodeGen::DoCheckMapCommon(Register reg,
 }
 
 
-void LCodeGen::DoCheckMap(LCheckMap* instr) {
+void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
   Register scratch = scratch0();
   LOperand* input = instr->InputAt(0);
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  Handle<Map> map = instr->hydrogen()->map();
-  DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
-                   instr->environment());
+
+  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);
 }
 
 
@@ -4464,6 +4616,14 @@ 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);
@@ -4482,14 +4642,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
@@ -4497,9 +4657,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
   __ mov(result, Operand(0));
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
-  __ LoadHeapObject(r0, constructor);
+  __ mov(r0, Operand(Smi::FromInt(instance_size)));
   __ push(r0);
-  CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr);
+  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
   __ StoreToSafepointRegisterSlot(r0, result);
 }
 
@@ -4633,9 +4793,10 @@ 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 = JSObject::GetElement(object, i);
+        Handle<Object> value(fast_elements->get(i));
         if (value->IsJSObject()) {
           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
           __ add(r2, result, Operand(*offset));
@@ -4659,6 +4820,23 @@ 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.
@@ -4954,7 +5132,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   Register strict = scratch0();
   __ mov(strict, Operand(Smi::FromInt(strict_mode_flag())));
   __ Push(object, key, strict);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -4967,7 +5145,7 @@ void LCodeGen::DoIn(LIn* instr) {
   Register obj = ToRegister(instr->object());
   Register key = ToRegister(instr->key());
   __ Push(key, obj);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
index adb6e1b..c6a3af7 100644 (file)
@@ -215,12 +215,18 @@ 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);
+                         CallKind call_kind,
+                         R1State r1_state);
 
   void LoadHeapObject(Register result, Handle<HeapObject> object);
 
@@ -317,6 +323,17 @@ 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(),
index 857c2bf..4da2fec 100644 (file)
@@ -3710,22 +3710,35 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
 }
 
 
-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;
+#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;
 }
+#endif
 
 
 CodePatcher::CodePatcher(byte* address, int instructions)
     : address_(address),
       instructions_(instructions),
       size_(instructions * Assembler::kInstrSize),
-      masm_(Isolate::Current(), address, size_ + Assembler::kGap) {
+      masm_(NULL, address, size_ + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
index 47afa93..360f4c1 100644 (file)
@@ -85,7 +85,14 @@ enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
 enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
 
 
-bool AreAliased(Register r1, Register r2, Register r3, Register r4);
+#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
 
 
 // MacroAssembler implements a collection of frequently used macros.
@@ -1321,7 +1328,6 @@ 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
@@ -1351,7 +1357,6 @@ 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
 
 
 // -----------------------------------------------------------------------------
index 10ff2dd..a833624 100644 (file)
@@ -452,8 +452,12 @@ void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c,
 void RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c,
                                                      uint32_t mask,
                                                      Label* on_equal) {
-  __ and_(r0, current_character(), Operand(mask));
-  __ cmp(r0, Operand(c));
+  if (c == 0) {
+    __ tst(current_character(), Operand(mask));
+  } else {
+    __ and_(r0, current_character(), Operand(mask));
+    __ cmp(r0, Operand(c));
+  }
   BranchOrBacktrack(eq, on_equal);
 }
 
@@ -461,8 +465,12 @@ void RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c,
 void RegExpMacroAssemblerARM::CheckNotCharacterAfterAnd(unsigned c,
                                                         unsigned mask,
                                                         Label* on_not_equal) {
-  __ and_(r0, current_character(), Operand(mask));
-  __ cmp(r0, Operand(c));
+  if (c == 0) {
+    __ tst(current_character(), Operand(mask));
+  } else {
+    __ and_(r0, current_character(), Operand(mask));
+    __ cmp(r0, Operand(c));
+  }
   BranchOrBacktrack(ne, on_not_equal);
 }
 
@@ -480,6 +488,44 @@ 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
index 5c8ed06..14f984f 100644 (file)
@@ -79,6 +79,14 @@ 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);
index 06f8385..49c0982 100644 (file)
@@ -443,8 +443,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
   Label exit;
 
   // Check that the map of the object hasn't changed.
+  CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
+                                             : REQUIRE_EXACT_MAP;
   __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label,
-              DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+              DO_SMI_CHECK, mode);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -580,6 +582,8 @@ static void PushInterceptorArguments(MacroAssembler* masm,
   __ push(holder);
   __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
   __ push(scratch);
+  __ mov(scratch, Operand(ExternalReference::isolate_address()));
+  __ push(scratch);
 }
 
 
@@ -594,7 +598,7 @@ static void CompileCallLoadPropertyWithInterceptor(
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate());
-  __ mov(r0, Operand(5));
+  __ mov(r0, Operand(6));
   __ mov(r1, Operand(ref));
 
   CEntryStub stub(1);
@@ -602,9 +606,9 @@ static void CompileCallLoadPropertyWithInterceptor(
 }
 
 
-static const int kFastApiCallArguments = 3;
+static const int kFastApiCallArguments = 4;
 
-// Reserves space for the extra arguments to FastHandleApiCall in the
+// Reserves space for the extra arguments to API function in the
 // caller's frame.
 //
 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
@@ -630,7 +634,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   //  -- sp[0]              : holder (set by CheckPrototypes)
   //  -- sp[4]              : callee JS function
   //  -- sp[8]              : call data
-  //  -- sp[12]             : last JS argument
+  //  -- sp[12]             : isolate
+  //  -- sp[16]             : last JS argument
   //  -- ...
   //  -- sp[(argc + 3) * 4] : first JS argument
   //  -- sp[(argc + 4) * 4] : receiver
@@ -640,7 +645,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   __ LoadHeapObject(r5, function);
   __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
 
-  // Pass the additional arguments FastHandleApiCall expects.
+  // Pass the additional arguments.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
@@ -649,13 +654,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   } else {
     __ Move(r6, call_data);
   }
-  // Store JS function and call data.
-  __ stm(ib, sp, r5.bit() | r6.bit());
+  __ mov(r7, Operand(ExternalReference::isolate_address()));
+  // Store JS function, call data and isolate.
+  __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
 
-  // r2 points to call data as expected by Arguments
-  // (refer to layout above).
-  __ add(r2, sp, Operand(2 * kPointerSize));
+  // Prepare arguments.
+  __ add(r2, sp, Operand(3 * 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 +671,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 = data
+  // v8::Arguments::implicit_args_
   __ str(r2, MemOperand(r0, 0 * kPointerSize));
-  // v8::Arguments::values = last argument
+  // v8::Arguments::values_
   __ add(ip, r2, Operand(argc * kPointerSize));
   __ str(ip, MemOperand(r0, 1 * kPointerSize));
   // v8::Arguments::length_ = argc
@@ -843,7 +850,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        5);
+        6);
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1202,7 +1209,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
   } else {
     __ Move(scratch3, Handle<Object>(callback->data()));
   }
-  __ Push(reg, scratch3, name_reg);
+  __ Push(reg, scratch3);
+  __ mov(scratch3, Operand(ExternalReference::isolate_address()));
+  __ Push(scratch3, name_reg);
   __ mov(r0, sp);  // r0 = Handle<String>
 
   const int kApiStackSpace = 1;
@@ -1214,7 +1223,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
   __ str(scratch2, MemOperand(sp, 1 * kPointerSize));
   __ add(r1, sp, Operand(1 * kPointerSize));  // r1 = AccessorInfo&
 
-  const int kStackUnwindSpace = 4;
+  const int kStackUnwindSpace = 5;
   Address getter_address = v8::ToCData<Address>(callback->getter());
   ApiFunction fun(getter_address);
   ExternalReference ref =
@@ -1264,12 +1273,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
                                           name, miss);
     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
 
+    // Preserve the receiver register explicitly whenever it is different from
+    // the holder and it is needed should the interceptor return without any
+    // result. The CALLBACKS case needs the receiver to be passed into C++ code,
+    // the FIELD case might cause a miss during the prototype check.
+    bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
+    bool must_preserve_receiver_reg = !receiver.is(holder_reg) &&
+        (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+
     // Save necessary data before invoking an interceptor.
     // Requires a frame to make GC aware of pushed pointers.
     {
       FrameScope frame_scope(masm(), StackFrame::INTERNAL);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-        // CALLBACKS case needs a receiver to be passed into C++ callback.
+      if (must_preserve_receiver_reg) {
         __ Push(receiver, holder_reg, name_reg);
       } else {
         __ Push(holder_reg, name_reg);
@@ -1294,14 +1310,14 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       __ bind(&interceptor_failed);
       __ pop(name_reg);
       __ pop(holder_reg);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      if (must_preserve_receiver_reg) {
         __ pop(receiver);
       }
       // Leave the internal frame.
     }
     // Check that the maps from interceptor's holder to lookup's holder
     // haven't changed.  And load lookup's holder into |holder| register.
-    if (*interceptor_holder != lookup->holder()) {
+    if (must_perfrom_prototype_check) {
       holder_reg = CheckPrototypes(interceptor_holder,
                                    holder_reg,
                                    Handle<JSObject>(lookup->holder()),
@@ -1335,20 +1351,19 @@ 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);
-        __ ldr(scratch3,
-               FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
-        __ Push(holder_reg, scratch3, scratch2, name_reg);
+        __ push(holder_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, 5, 1);
+      __ TailCallExternalReference(ref, 6, 1);
     }
   } else {  // !compile_followup_inline
     // Call the runtime system to load the interceptor.
@@ -1362,7 +1377,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
                           masm()->isolate());
-    __ TailCallExternalReference(ref, 5, 1);
+    __ TailCallExternalReference(ref, 6, 1);
   }
 }
 
@@ -1730,7 +1745,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, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag));
+  __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize));
   __ cmp(r0, r6);
   __ b(eq, &call_builtin);
 
@@ -1738,7 +1753,7 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall(
   __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
 
   // Fill with the hole.
-  __ str(r6, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag));
+  __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize));
   __ Drop(argc + 1);
   __ Ret();
 
@@ -3368,6 +3383,44 @@ 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) {
@@ -3384,8 +3437,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.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
 
   __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
   // r3: elements array
@@ -3715,8 +3768,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.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
 
   __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
 
@@ -4041,8 +4094,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.
-  __ JumpIfNotSmi(r0, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, r0, r4, r5, d1, &miss_force_generic);
 
   // Get the elements array.
   __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
@@ -4093,8 +4146,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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // 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);
 
   // Get the elements array.
   __ ldr(elements_reg,
@@ -4169,8 +4222,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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // 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);
 
   if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
     __ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4336,7 +4389,9 @@ 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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  // 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);
 
   __ ldr(elements_reg,
          FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
@@ -4427,6 +4482,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
     // Increment the length of the array.
     __ mov(length_reg, Operand(Smi::FromInt(1)));
     __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+    __ ldr(elements_reg,
+           FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
index daa75d5..9f2c8de 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2010 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:
@@ -465,15 +465,19 @@ 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] = this;
+  arrays[0] = array;
   for (var i = 0; i < arg_count; i++) {
     arrays[i + 1] = %_Arguments(i);
   }
@@ -1023,13 +1027,28 @@ function ArrayFilter(f, receiver) {
   var result = new $Array();
   var accumulator = new InternalArray();
   var accumulator_length = 0;
-  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;
+  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;
+        }
       }
     }
+    // End of duplicate.
   }
   %MoveArrayContents(accumulator, result);
   return result;
@@ -1055,12 +1074,24 @@ function ArrayForEach(f, receiver) {
   } else if (!IS_SPEC_OBJECT(receiver)) {
     receiver = ToObject(receiver);
   }
-
-  for (var i = 0; i < length; i++) {
-    if (i in array) {
-      var element = array[i];
-      %_CallFunction(receiver, element, i, array, f);
+  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);
+      }
+    }
+    // End of duplicate.
   }
 }
 
@@ -1087,11 +1118,24 @@ function ArraySome(f, receiver) {
     receiver = ToObject(receiver);
   }
 
-  for (var i = 0; i < length; i++) {
-    if (i in array) {
-      var element = array[i];
-      if (%_CallFunction(receiver, element, i, array, f)) return true;
+  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;
+      }
     }
+    // End of duplicate.
   }
   return false;
 }
@@ -1117,11 +1161,24 @@ function ArrayEvery(f, receiver) {
     receiver = ToObject(receiver);
   }
 
-  for (var i = 0; i < length; i++) {
-    if (i in array) {
-      var element = array[i];
-      if (!%_CallFunction(receiver, element, i, array, f)) return false;
+  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;
+      }
     }
+    // End of duplicate.
   }
   return true;
 }
@@ -1148,11 +1205,24 @@ function ArrayMap(f, receiver) {
 
   var result = new $Array();
   var accumulator = new InternalArray(length);
-  for (var i = 0; i < length; i++) {
-    if (i in array) {
-      var element = array[i];
-      accumulator[i] = %_CallFunction(receiver, element, i, array, f);
+  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);
+      }
     }
+  } 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;
@@ -1307,11 +1377,27 @@ function ArrayReduce(callback, current) {
   }
 
   var receiver = %GetDefaultReceiver(callback);
-  for (; i < length; i++) {
-    if (i in array) {
-      var element = array[i];
-      current = %_CallFunction(receiver, current, element, i, array, 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);
+      }
     }
+    // End of duplicate.
   }
   return current;
 }
@@ -1344,11 +1430,27 @@ function ArrayReduceRight(callback, current) {
   }
 
   var receiver = %GetDefaultReceiver(callback);
-  for (; i >= 0; i--) {
-    if (i in array) {
-      var element = array[i];
-      current = %_CallFunction(receiver, current, element, i, array, 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);
+      }
     }
+    // End of duplicate.
   }
   return current;
 }
index 4944202..be25649 100644 (file)
@@ -99,21 +99,7 @@ struct DoubleConstant BASE_EMBEDDED {
   double the_hole_nan;
 };
 
-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;
+static DoubleConstant double_constants;
 
 const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
 
@@ -726,6 +712,18 @@ 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))) {}
 
@@ -958,50 +956,47 @@ ExternalReference ExternalReference::scheduled_exception_address(
 
 
 ExternalReference ExternalReference::address_of_min_int() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->min_int));
+  return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int));
 }
 
 
 ExternalReference ExternalReference::address_of_one_half() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->one_half));
+  return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half));
 }
 
 
 ExternalReference ExternalReference::address_of_minus_zero() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->minus_zero));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.minus_zero));
 }
 
 
 ExternalReference ExternalReference::address_of_zero() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->zero));
+  return ExternalReference(reinterpret_cast<void*>(&double_constants.zero));
 }
 
 
 ExternalReference ExternalReference::address_of_uint8_max_value() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->uint8_max_value));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.uint8_max_value));
 }
 
 
 ExternalReference ExternalReference::address_of_negative_infinity() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->negative_infinity));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.negative_infinity));
 }
 
 
 ExternalReference ExternalReference::address_of_canonical_non_hole_nan() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->canonical_non_hole_nan));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan));
 }
 
 
 ExternalReference ExternalReference::address_of_the_hole_nan() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->the_hole_nan));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.the_hole_nan));
 }
 
 
@@ -1158,6 +1153,20 @@ 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();
index 918a2a6..05fe320 100644 (file)
@@ -62,6 +62,10 @@ class AssemblerBase: public Malloced {
   Isolate* isolate() const { return isolate_; }
   int jit_cookie() { return jit_cookie_; }
 
+  // Overwrite a host NaN with a quiet target NaN.  Used by mksnapshot for
+  // cross-snapshotting.
+  static void QuietNaN(HeapObject* nan) { }
+
  private:
   Isolate* isolate_;
   int jit_cookie_;
@@ -535,6 +539,8 @@ class ExternalReference BASE_EMBEDDED {
     DIRECT_GETTER_CALL
   };
 
+  static void SetUp();
+
   typedef void* ExternalReferenceRedirector(void* original, Type type);
 
   ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
index 4b6ae68..6f9fd7a 100644 (file)
@@ -962,6 +962,14 @@ 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);
@@ -969,13 +977,10 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
   max_match_ = 0;
   for (int i = 0; i < nodes->length(); i++) {
     RegExpTree* node = nodes->at(i);
-    min_match_ += node->min_match();
+    int node_min_match = node->min_match();
+    min_match_ = IncreaseBy(min_match_, node_min_match);
     int node_max_match = node->max_match();
-    if (kInfinity - max_match_ < node_max_match) {
-      max_match_ = kInfinity;
-    } else {
-      max_match_ += node->max_match();
-    }
+    max_match_ = IncreaseBy(max_match_, node_max_match);
   }
 }
 
@@ -993,138 +998,78 @@ CaseClause::CaseClause(Isolate* isolate,
 }
 
 
-#define INCREASE_NODE_COUNT(NodeType) \
+#define REGULAR_NODE(NodeType) \
   void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
     increase_node_count(); \
   }
+#define DONT_OPTIMIZE_NODE(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); \
+  }
 
-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.
-}
-
+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)
 
 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
   increase_node_count();
@@ -1142,6 +1087,11 @@ 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_);
index b827302..dad8057 100644 (file)
@@ -270,6 +270,7 @@ 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(); }
@@ -420,8 +421,8 @@ class Block: public BreakableStatement {
   ZoneList<Statement*>* statements() { return &statements_; }
   bool is_initializer_block() const { return is_initializer_block_; }
 
-  Scope* block_scope() const { return block_scope_; }
-  void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
+  Scope* scope() const { return scope_; }
+  void set_scope(Scope* scope) { scope_ = scope; }
 
  protected:
   template<class> friend class AstNodeFactory;
@@ -433,13 +434,13 @@ class Block: public BreakableStatement {
       : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
         statements_(capacity),
         is_initializer_block_(is_initializer_block),
-        block_scope_(NULL) {
+        scope_(NULL) {
   }
 
  private:
   ZoneList<Statement*> statements_;
   bool is_initializer_block_;
-  Scope* block_scope_;
+  Scope* scope_;
 };
 
 
@@ -607,6 +608,7 @@ 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;
@@ -618,6 +620,7 @@ class ModuleLiteral: public Module {
 
  private:
   Block* body_;
+  Handle<Context> context_;
 };
 
 
index 0e95b4b..c65c68c 100644 (file)
@@ -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->empty_string());
+                                 heap->query_colon_symbol());
     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 = PropertyDetails(descs->GetDetails(i));
+      PropertyDetails details = descs->GetDetails(i);
       switch (details.type()) {
         case FIELD: {
           HandleScope inner;
index 0f493e6..6d1c6a9 100644 (file)
@@ -412,12 +412,19 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
   HeapObject* elms = array->elements();
   Map* map = elms->map();
   if (map == heap->fixed_array_map()) {
-    if (args == NULL || !array->HasFastSmiOnlyElements()) {
+    if (array->HasFastElements()) return elms;
+    if (args == NULL) {
+      if (array->HasFastDoubleElements()) {
+        ASSERT(elms == heap->empty_fixed_array());
+        MaybeObject* maybe_transition =
+            array->TransitionElementsKind(FAST_ELEMENTS);
+        if (maybe_transition->IsFailure()) return maybe_transition;
+      }
       return elms;
     }
   } else if (map == heap->fixed_cow_array_map()) {
     MaybeObject* maybe_writable_result = array->EnsureWritableFastElements();
-    if (args == NULL || !array->HasFastSmiOnlyElements() ||
+    if (args == NULL || array->HasFastElements() ||
         maybe_writable_result->IsFailure()) {
       return maybe_writable_result;
     }
@@ -1098,7 +1105,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
 
     CustomArguments custom(isolate);
     v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
-        data_obj, *function, raw_holder);
+        isolate, data_obj, *function, raw_holder);
 
     v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
         custom.end(),
@@ -1138,68 +1145,6 @@ 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).
@@ -1238,7 +1183,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
 
     CustomArguments custom(isolate);
     v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
-        call_data->data(), constructor, obj);
+        isolate, call_data->data(), constructor, obj);
     v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
         custom.end(),
         &args[0] - 1,
index f079139..3ea3393 100644 (file)
@@ -56,7 +56,6 @@ 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)                 \
index b13efb3..c7cc66e 100644 (file)
@@ -72,24 +72,23 @@ 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 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                        */
+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                        */
 
 #define DECLARE_BYTECODES(name, code, length) \
   static const int BC_##name = code;
index 11016c8..814e358 100644 (file)
@@ -73,21 +73,12 @@ 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
 }
 
 
@@ -125,8 +116,16 @@ Handle<Code> CodeStub::GetCode() {
         GetICState());
     Handle<Code> new_object = factory->NewCode(
         desc, flags, masm.CodeObject(), NeedsImmovableCode());
-    RecordCodeGeneration(*new_object, &masm);
+    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
 
     if (UseSpecialCache()) {
       AddToSpecialCache(new_object);
index b67e961..5c87178 100644 (file)
@@ -498,6 +498,7 @@ class ICCompareStub: public CodeStub {
 
   virtual void FinishCode(Handle<Code> code) {
     code->set_compare_state(state_);
+    code->set_compare_operation(op_);
   }
 
   virtual CodeStub::Major MajorKey() { return CompareIC; }
index 3b9c59e..b73e8ac 100644 (file)
@@ -40,6 +40,9 @@ 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__
@@ -51,6 +54,10 @@ 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)
@@ -68,6 +75,16 @@ 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
index 2272337..c9c2480 100644 (file)
@@ -531,6 +531,10 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
     if (extension == NULL && !result.is_null()) {
       compilation_cache->PutScript(source, result);
     }
+  } else {
+    if (result->ic_age() != HEAP->global_ic_age()) {
+      result->ResetForNewContext(HEAP->global_ic_age());
+    }
   }
 
   if (result.is_null()) isolate->ReportPendingMessages();
@@ -586,6 +590,10 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
       compilation_cache->PutEval(
           source, context, is_global, result, scope_position);
     }
+  } else {
+    if (result->ic_age() != HEAP->global_ic_age()) {
+      result->ResetForNewContext(HEAP->global_ic_age());
+    }
   }
 
   return result;
index af5cb03..647c15c 100644 (file)
@@ -397,7 +397,7 @@ class Context: public FixedArray {
   GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSORS)
 #undef GLOBAL_CONTEXT_FIELD_ACCESSORS
 
-  // Lookup the the slot called name, starting with the current context.
+  // Lookup the slot called name, starting with the current context.
   // There are three possibilities:
   //
   // 1) result->IsContext():
index b098a1c..77b260f 100644 (file)
@@ -228,9 +228,7 @@ double InternalStringToIntDouble(UnicodeCache* unicode_cache,
   }
 
   ASSERT(number != 0);
-  // 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);
+  return ldexp(static_cast<double>(negative ? -number : number), exponent);
 }
 
 
index 45781cf..adbe550 100644 (file)
@@ -315,9 +315,10 @@ static size_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
 }
 
 
-const char kArrayBufferReferencePropName[] = "_is_array_buffer_";
-const char kArrayBufferMarkerPropName[] = "_array_buffer_ref_";
+const char kArrayBufferMarkerPropName[] = "_is_array_buffer_";
+const char kArrayBufferReferencePropName[] = "_array_buffer_ref_";
 
+static const int kExternalArrayAllocationHeaderSize = 2;
 
 Handle<Value> Shell::CreateExternalArray(const Arguments& args,
                                          ExternalArrayType type,
@@ -352,10 +353,11 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
 
   Local<Value> length_value = (args.Length() < 3)
       ? (first_arg_is_array_buffer
-         ? args[0]->ToObject()->Get(String::New("length"))
+         ? args[0]->ToObject()->Get(String::New("byteLength"))
          : args[0])
       : args[2];
-  size_t length = convertToUint(length_value, &try_catch);
+  size_t byteLength = convertToUint(length_value, &try_catch);
+  size_t length = byteLength;
   if (try_catch.HasCaught()) return try_catch.Exception();
 
   void* data = NULL;
@@ -367,7 +369,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
     data = derived_from->GetIndexedPropertiesExternalArrayData();
 
     size_t array_buffer_length = convertToUint(
-        derived_from->Get(String::New("length")),
+        derived_from->Get(String::New("byteLength")),
         &try_catch);
     if (try_catch.HasCaught()) return try_catch.Exception();
 
@@ -426,22 +428,44 @@ 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) {
-    data = calloc(length, element_size);
+    // 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);
     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,
       static_cast<int>(length));
-  array->Set(String::New("length"),
-             Int32::New(static_cast<int32_t>(length)), ReadOnly);
-  array->Set(String::New("BYTES_PER_ELEMENT"),
-             Int32::New(static_cast<int32_t>(element_size)));
+  array->Set(String::New("byteLength"),
+             Int32::New(static_cast<int32_t>(byteLength)), ReadOnly);
+  if (!is_array_buffer_construct) {
+    array->Set(String::New("length"),
+               Int32::New(static_cast<int32_t>(length)), ReadOnly);
+    array->Set(String::New("byteOffset"),
+               Int32::New(static_cast<int32_t>(offset)), ReadOnly);
+    array->Set(String::New("BYTES_PER_ELEMENT"),
+               Int32::New(static_cast<int32_t>(element_size)));
+    // We currently support 'buffer' property only if constructed from a buffer.
+    if (first_arg_is_array_buffer) {
+      array->Set(String::New("buffer"), args[0], ReadOnly);
+    }
+  }
   return array;
 }
 
@@ -452,6 +476,9 @@ 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();
@@ -808,6 +835,8 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
   global_template->Set(String::New("read"), FunctionTemplate::New(Read));
   global_template->Set(String::New("readbinary"),
                        FunctionTemplate::New(ReadBinary));
+  global_template->Set(String::New("readbuffer"),
+                       FunctionTemplate::New(ReadBuffer));
   global_template->Set(String::New("readline"),
                        FunctionTemplate::New(ReadLine));
   global_template->Set(String::New("load"), FunctionTemplate::New(Load));
@@ -977,8 +1006,8 @@ void Shell::OnExit() {
     printf("+--------------------------------------------+-------------+\n");
     delete [] counters;
   }
-  if (counters_file_ != NULL)
-    delete counters_file_;
+  delete counters_file_;
+  delete counter_map_;
 }
 #endif  // V8_SHARED
 
@@ -1043,6 +1072,32 @@ Handle<Value> Shell::ReadBinary(const Arguments& args) {
 }
 
 
+Handle<Value> Shell::ReadBuffer(const Arguments& args) {
+  String::Utf8Value filename(args[0]);
+  int length;
+  if (*filename == NULL) {
+    return ThrowException(String::New("Error loading file"));
+  }
+  char* data = ReadChars(*filename, &length);
+  if (data == NULL) {
+    return ThrowException(String::New("Error reading file"));
+  }
+
+  Handle<Object> buffer = Object::New();
+  buffer->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
+
+  Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer);
+  persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback);
+  persistent_buffer.MarkIndependent();
+
+  buffer->SetIndexedPropertiesToExternalArrayData(
+      reinterpret_cast<uint8_t*>(data), kExternalUnsignedByteArray, length);
+  buffer->Set(String::New("byteLength"),
+             Int32::New(static_cast<int32_t>(length)), ReadOnly);
+  return buffer;
+}
+
+
 #ifndef V8_SHARED
 static char* ReadToken(char* data, char token) {
   char* next = i::OS::StrChr(data, token);
index c872f90..23fdebc 100644 (file)
@@ -308,6 +308,7 @@ class Shell : public i::AllStatic {
   static Handle<Value> DisableProfiler(const Arguments& args);
   static Handle<Value> Read(const Arguments& args);
   static Handle<Value> ReadBinary(const Arguments& args);
+  static Handle<Value> ReadBuffer(const Arguments& args);
   static Handle<String> ReadFromStdin();
   static Handle<Value> ReadLine(const Arguments& args) {
     return ReadFromStdin();
index bf26923..819135a 100644 (file)
@@ -2174,7 +2174,7 @@ function DebugResponseDetails(response) {
           }
 
           var current_line = from_line + num;
-          spacer = maxdigits - (1 + Math.floor(log10(current_line)));
+          var spacer = maxdigits - (1 + Math.floor(log10(current_line)));
           if (current_line == Debug.State.currentSourceLine + 1) {
             for (var i = 0; i < maxdigits; i++) {
               result += '>';
index 75edf6d..d0e24ab 100644 (file)
@@ -516,8 +516,7 @@ function DateSetMilliseconds(ms) {
   var t = LOCAL_DATE_VALUE(this);
   ms = ToNumber(ms);
   var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
-  SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
-  return this;
+  return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
 }
 
 
index bdc7a57..511663d 100644 (file)
@@ -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.
 
index 802f622..91838e8 100644 (file)
@@ -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) {
-      return response.failed('Invalid frame number');
+      throw new Error('Invalid frame number');
     }
     return this.exec_state_.frame(frame_index);
   } else {
@@ -1966,20 +1966,44 @@ DebugCommandProcessor.prototype.frameForScopeRequest_ = function(request) {
 };
 
 
-DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
-  // No frames no scopes.
-  if (this.exec_state_.frameCount() == 0) {
-    return response.failed('No scopes');
+// 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;
   }
+}
 
-  // Get the frame for which the scopes are requested.
-  var frame = this.frameForScopeRequest_(request);
 
-  // Fill all scopes for this frame.
-  var total_scopes = frame.scopeCount();
+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();
   var scopes = [];
   for (var i = 0; i < total_scopes; i++) {
-    scopes.push(frame.scope(i));
+    scopes.push(scope_holder.scope(i));
   }
   response.body = {
     fromScope: 0,
@@ -1991,24 +2015,19 @@ DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
 
 
 DebugCommandProcessor.prototype.scopeRequest_ = function(request, response) {
-  // 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);
+  // Get the frame or function for which the scope is requested.
+  var scope_holder = this.scopeHolderForScopeRequest_(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 || frame.scopeCount() <= scope_index) {
+    if (scope_index < 0 || scope_holder.scopeCount() <= scope_index) {
       return response.failed('Invalid scope number');
     }
   }
 
-  response.body = frame.scope(scope_index);
+  response.body = scope_holder.scope(scope_index);
 };
 
 
index f8a1ecf..9efb5c3 100644 (file)
@@ -892,6 +892,16 @@ void Debug::Iterate(ObjectVisitor* v) {
 }
 
 
+void Debug::PutValuesOnStackAndDie(int start,
+                                   Address c_entry_fp,
+                                   Address last_fp,
+                                   Address larger_fp,
+                                   int count,
+                                   int end) {
+  OS::Abort();
+}
+
+
 Object* Debug::Break(Arguments args) {
   Heap* heap = isolate_->heap();
   HandleScope scope(isolate_);
@@ -984,11 +994,34 @@ Object* Debug::Break(Arguments args) {
       // Count frames until target frame
       int count = 0;
       JavaScriptFrameIterator it(isolate_);
-      while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) {
+      while (!it.done() && it.frame()->fp() < thread_local_.last_fp_) {
         count++;
         it.Advance();
       }
 
+      // Catch the cases that would lead to crashes and capture
+      // - C entry FP at which to start stack crawl.
+      // - FP of the frame at which we plan to stop stepping out (last FP).
+      // - current FP that's larger than last FP.
+      // - Counter for the number of steps to step out.
+      if (it.done()) {
+        // We crawled the entire stack, never reaching last_fp_.
+        PutValuesOnStackAndDie(0xBEEEEEEE,
+                               frame->fp(),
+                               thread_local_.last_fp_,
+                               NULL,
+                               count,
+                               0xFEEEEEEE);
+      } else if (it.frame()->fp() != thread_local_.last_fp_) {
+        // We crawled over last_fp_, without getting a match.
+        PutValuesOnStackAndDie(0xBEEEEEEE,
+                               frame->fp(),
+                               thread_local_.last_fp_,
+                               it.frame()->fp(),
+                               count,
+                               0xFEEEEEEE);
+      }
+
       // If we found original frame
       if (it.frame()->fp() == thread_local_.last_fp_) {
         if (step_count > 1) {
@@ -1857,13 +1890,6 @@ 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) {
@@ -2234,6 +2260,13 @@ void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
 }
 
 
+const int Debug::FramePaddingLayout::kInitialSize = 1;
+
+
+// Any even value bigger than kInitialSize as needed for stack scanning.
+const int Debug::FramePaddingLayout::kPaddingValue = kInitialSize + 1;
+
+
 bool Debug::IsDebugGlobal(GlobalObject* global) {
   return IsLoaded() && global == debug_context()->global();
 }
index 474b90b..d9c966c 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -232,6 +232,12 @@ class Debug {
   void PreemptionWhileInDebugger();
   void Iterate(ObjectVisitor* v);
 
+  NO_INLINE(void PutValuesOnStackAndDie(int start,
+                                        Address c_entry_fp,
+                                        Address last_fp,
+                                        Address larger_fp,
+                                        int count,
+                                        int end));
   Object* Break(Arguments args);
   void SetBreakPoint(Handle<SharedFunctionInfo> shared,
                      Handle<Object> break_point_object,
@@ -245,6 +251,8 @@ 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);
@@ -455,6 +463,50 @@ class Debug {
   // Architecture-specific constant.
   static const bool kFrameDropperSupported;
 
+  /**
+   * Defines layout of a stack frame that supports padding. This is a regular
+   * internal frame that has a flexible stack structure. LiveEdit can shift
+   * its lower part up the stack, taking up the 'padding' space when additional
+   * stack memory is required.
+   * Such frame is expected immediately above the topmost JavaScript frame.
+   *
+   * Stack Layout:
+   *   --- Top
+   *   LiveEdit routine frames
+   *   ---
+   *   C frames of debug handler
+   *   ---
+   *   ...
+   *   ---
+   *      An internal frame that has n padding words:
+   *      - any number of words as needed by code -- upper part of frame
+   *      - padding size: a Smi storing n -- current size of padding
+   *      - padding: n words filled with kPaddingValue in form of Smi
+   *      - 3 context/type words of a regular InternalFrame
+   *      - fp
+   *   ---
+   *      Topmost JavaScript frame
+   *   ---
+   *   ...
+   *   --- Bottom
+   */
+  class FramePaddingLayout : public AllStatic {
+   public:
+    // Architecture-specific constant.
+    static const bool kIsSupported;
+
+    // A size of frame base including fp. Padding words starts right above
+    // the base.
+    static const int kFrameBaseSize = 4;
+
+    // A number of words that should be reserved on stack for the LiveEdit use.
+    // Normally equals 1. Stored on stack in form of Smi.
+    static const int kInitialSize;
+    // A value that padding words are filled with (in form of Smi). Going
+    // bottom-top, the first word not having this value is a counter word.
+    static const int kPaddingValue;
+  };
+
  private:
   explicit Debug(Isolate* isolate);
   ~Debug();
@@ -464,7 +516,6 @@ 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);
index 16a3245..fcf6906 100644 (file)
@@ -130,12 +130,6 @@ 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) &&
index 1d043a1..d367af8 100644 (file)
@@ -199,10 +199,13 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
     }
 #endif
   }
-  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length());
   ASSERT(to != from);
   ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
   if (copy_size == 0) return;
+  uint32_t to_length = to->length();
+  if (to_start + copy_size > to_length) {
+    copy_size = to_length - to_start;
+  }
   for (int i = 0; i < copy_size; i++) {
     int entry = from->FindEntry(i + from_start);
     if (entry != SeededNumberDictionary::kNotFound) {
@@ -356,8 +359,11 @@ static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from,
       }
     }
   }
-  ASSERT(copy_size + static_cast<int>(to_start) <= to->length());
   if (copy_size == 0) return;
+  uint32_t to_length = to->length();
+  if (to_start + copy_size > to_length) {
+    copy_size = to_length - to_start;
+  }
   for (int i = 0; i < copy_size; i++) {
     int entry = from->FindEntry(i + from_start);
     if (entry != SeededNumberDictionary::kNotFound) {
@@ -418,10 +424,10 @@ class ElementsAccessorBase : public ElementsAccessor {
         receiver, holder, key, BackingStore::cast(backing_store));
   }
 
-  virtual MaybeObject* Get(Object* receiver,
-                           JSObject* holder,
-                           uint32_t key,
-                           FixedArrayBase* backing_store) {
+  MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver,
+                                           JSObject* holder,
+                                           uint32_t key,
+                                           FixedArrayBase* backing_store) {
     if (backing_store == NULL) {
       backing_store = holder->elements();
     }
@@ -429,62 +435,64 @@ class ElementsAccessorBase : public ElementsAccessor {
         receiver, holder, key, BackingStore::cast(backing_store));
   }
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              BackingStore* backing_store) {
+  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
+                                              JSObject* obj,
+                                              uint32_t key,
+                                              BackingStore* backing_store) {
     return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
            ? backing_store->get(key)
            : backing_store->GetHeap()->the_hole_value();
   }
 
-  virtual MaybeObject* SetLength(JSArray* array,
-                                 Object* length) {
+  MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array,
+                                                 Object* length) {
     return ElementsAccessorSubclass::SetLengthImpl(
         array, length, BackingStore::cast(array->elements()));
   }
 
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    BackingStore* backing_store);
+  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
+      JSObject* obj,
+      Object* length,
+      BackingStore* backing_store);
 
-  virtual MaybeObject* SetCapacityAndLength(JSArray* array,
-                                            int capacity,
-                                            int length) {
+  MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength(JSArray* array,
+                                                            int capacity,
+                                                            int length) {
     return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
         array,
         capacity,
         length);
   }
 
-  static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
-                                                       int capacity,
-                                                       int length) {
+  MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength(
+      JSObject* obj,
+      int capacity,
+      int length) {
     UNIMPLEMENTED();
     return obj;
   }
 
-  virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) = 0;
+  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
+                                              uint32_t key,
+                                              JSReceiver::DeleteMode mode) = 0;
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
+  MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
+                                                       uint32_t from_start,
+                                                       FixedArrayBase* to,
+                                                       ElementsKind to_kind,
+                                                       uint32_t to_start,
+                                                       int copy_size) {
     UNREACHABLE();
     return NULL;
   }
 
-  virtual MaybeObject* CopyElements(JSObject* from_holder,
-                                    uint32_t from_start,
-                                    FixedArrayBase* to,
-                                    ElementsKind to_kind,
-                                    uint32_t to_start,
-                                    int copy_size,
-                                    FixedArrayBase* from) {
+  MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
+                                                    uint32_t from_start,
+                                                    FixedArrayBase* to,
+                                                    ElementsKind to_kind,
+                                                    uint32_t to_start,
+                                                    int copy_size,
+                                                    FixedArrayBase* from) {
     if (from == NULL) {
       from = from_holder->elements();
     }
@@ -495,10 +503,11 @@ class ElementsAccessorBase : public ElementsAccessor {
         from, from_start, to, to_kind, to_start, copy_size);
   }
 
-  virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
-                                               JSObject* holder,
-                                               FixedArray* to,
-                                               FixedArrayBase* from) {
+  MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
+      Object* receiver,
+      JSObject* holder,
+      FixedArray* to,
+      FixedArrayBase* from) {
     int len0 = to->length();
 #ifdef DEBUG
     if (FLAG_enable_slow_asserts) {
@@ -860,27 +869,28 @@ class ExternalElementsAccessor
   friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
                                     ElementsKindTraits<Kind> >;
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              BackingStore* backing_store) {
+  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
+                                              JSObject* obj,
+                                              uint32_t key,
+                                              BackingStore* backing_store) {
     return
         key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
         ? backing_store->get(key)
         : backing_store->GetHeap()->undefined_value();
   }
 
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    BackingStore* backing_store) {
+  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
+      JSObject* obj,
+      Object* length,
+      BackingStore* backing_store) {
     // External arrays do not support changing their length.
     UNREACHABLE();
     return obj;
   }
 
-  virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
+                                              uint32_t key,
+                                              JSReceiver::DeleteMode mode) {
     // External arrays always ignore deletes.
     return obj->GetHeap()->true_value();
   }
@@ -996,10 +1006,11 @@ class DictionaryElementsAccessor
 
   // Adjusts the length of the dictionary backing store and returns the new
   // length according to ES5 section 15.4.5.2 behavior.
-  static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
-                                                JSArray* array,
-                                                Object* length_object,
-                                                uint32_t length) {
+  MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
+      SeededNumberDictionary* dict,
+      JSArray* array,
+      Object* length_object,
+      uint32_t length) {
     if (length == 0) {
       // If the length of a slow array is reset to zero, we clear
       // the array and flush backing storage. This has the added
@@ -1051,9 +1062,10 @@ class DictionaryElementsAccessor
     return length_object;
   }
 
-  static MaybeObject* DeleteCommon(JSObject* obj,
-                                   uint32_t key,
-                                   JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT static MaybeObject* DeleteCommon(
+      JSObject* obj,
+      uint32_t key,
+      JSReceiver::DeleteMode mode) {
     Isolate* isolate = obj->GetIsolate();
     Heap* heap = isolate->heap();
     FixedArray* backing_store = FixedArray::cast(obj->elements());
@@ -1096,12 +1108,12 @@ class DictionaryElementsAccessor
     return heap->true_value();
   }
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
+  MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
+                                                       uint32_t from_start,
+                                                       FixedArrayBase* to,
+                                                       ElementsKind to_kind,
+                                                       uint32_t to_start,
+                                                       int copy_size) {
     switch (to_kind) {
       case FAST_SMI_ONLY_ELEMENTS:
       case FAST_ELEMENTS:
@@ -1125,16 +1137,17 @@ class DictionaryElementsAccessor
   friend class ElementsAccessorBase<DictionaryElementsAccessor,
                                     ElementsKindTraits<DICTIONARY_ELEMENTS> >;
 
-  virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
+                                              uint32_t key,
+                                              JSReceiver::DeleteMode mode) {
     return DeleteCommon(obj, key, mode);
   }
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              SeededNumberDictionary* backing_store) {
+  MUST_USE_RESULT static MaybeObject* GetImpl(
+      Object* receiver,
+      JSObject* obj,
+      uint32_t key,
+      SeededNumberDictionary* backing_store) {
     int entry = backing_store->FindEntry(key);
     if (entry != SeededNumberDictionary::kNotFound) {
       Object* element = backing_store->ValueAt(entry);
@@ -1180,10 +1193,10 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
       NonStrictArgumentsElementsAccessor,
       ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
 
-  static MaybeObject* GetImpl(Object* receiver,
-                              JSObject* obj,
-                              uint32_t key,
-                              FixedArray* parameter_map) {
+  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
+                                              JSObject* obj,
+                                              uint32_t key,
+                                              FixedArray* parameter_map) {
     Object* probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
       Context* context = Context::cast(parameter_map->get(0));
@@ -1210,18 +1223,19 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
     }
   }
 
-  static MaybeObject* SetLengthImpl(JSObject* obj,
-                                    Object* length,
-                                    FixedArray* parameter_map) {
+  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
+      JSObject* obj,
+      Object* length,
+      FixedArray* parameter_map) {
     // TODO(mstarzinger): This was never implemented but will be used once we
     // correctly implement [[DefineOwnProperty]] on arrays.
     UNIMPLEMENTED();
     return obj;
   }
 
-  virtual MaybeObject* Delete(JSObject* obj,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) {
+  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj,
+                                              uint32_t key,
+                                              JSReceiver::DeleteMode mode) {
     FixedArray* parameter_map = FixedArray::cast(obj->elements());
     Object* probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
@@ -1240,12 +1254,12 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
     return obj->GetHeap()->true_value();
   }
 
-  static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
-                                       uint32_t from_start,
-                                       FixedArrayBase* to,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
-                                       int copy_size) {
+  MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
+                                                       uint32_t from_start,
+                                                       FixedArrayBase* to,
+                                                       ElementsKind to_kind,
+                                                       uint32_t to_start,
+                                                       int copy_size) {
     FixedArray* parameter_map = FixedArray::cast(from);
     FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
     ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
@@ -1326,18 +1340,8 @@ 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) element_accessors.Kind##_handler,
+#define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
     ELEMENTS_LIST(ACCESSOR_ARRAY)
 #undef ACCESSOR_ARRAY
   };
@@ -1349,9 +1353,17 @@ 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>::
+MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
+                                                  ElementsKindTraits>::
     SetLengthImpl(JSObject* obj,
                   Object* length,
                   typename ElementsKindTraits::BackingStore* backing_store) {
index ff97c08..55d6fa5 100644 (file)
@@ -60,18 +60,19 @@ class ElementsAccessor {
   // can optionally pass in the backing store to use for the check, which must
   // be compatible with the ElementsKind of the ElementsAccessor. If
   // backing_store is NULL, the holder->elements() is used as the backing store.
-  virtual MaybeObject* Get(Object* receiver,
-                           JSObject* holder,
-                           uint32_t key,
-                           FixedArrayBase* backing_store = NULL) = 0;
+  MUST_USE_RESULT virtual MaybeObject* Get(
+      Object* receiver,
+      JSObject* holder,
+      uint32_t key,
+      FixedArrayBase* backing_store = NULL) = 0;
 
   // Modifies the length data property as specified for JSArrays and resizes the
   // underlying backing store accordingly. The method honors the semantics of
   // changing array sizes as defined in EcmaScript 5.1 15.4.5.2, i.e. array that
   // have non-deletable elements can only be shrunk to the size of highest
   // element that is non-deletable.
-  virtual MaybeObject* SetLength(JSArray* holder,
-                                 Object* new_length) = 0;
+  MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* holder,
+                                                 Object* new_length) = 0;
 
   // Modifies both the length and capacity of a JSArray, resizing the underlying
   // backing store as necessary. This method does NOT honor the semantics of
@@ -79,14 +80,14 @@ class ElementsAccessor {
   // elements. This method should only be called for array expansion OR by
   // runtime JavaScript code that use InternalArrays and don't care about
   // EcmaScript 5.1 semantics.
-  virtual MaybeObject* SetCapacityAndLength(JSArray* array,
-                                            int capacity,
-                                            int length) = 0;
+  MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength(JSArray* array,
+                                                            int capacity,
+                                                            int length) = 0;
 
   // Deletes an element in an object, returning a new elements backing store.
-  virtual MaybeObject* Delete(JSObject* holder,
-                              uint32_t key,
-                              JSReceiver::DeleteMode mode) = 0;
+  MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* holder,
+                                              uint32_t key,
+                                              JSReceiver::DeleteMode mode) = 0;
 
   // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
   // of elements from source after source_start to the destination array.
@@ -101,26 +102,28 @@ class ElementsAccessor {
   // the source JSObject or JSArray in source_holder. If the holder's backing
   // store is available, it can be passed in source and source_holder is
   // ignored.
-  virtual MaybeObject* CopyElements(JSObject* source_holder,
-                                    uint32_t source_start,
-                                    FixedArrayBase* destination,
-                                    ElementsKind destination_kind,
-                                    uint32_t destination_start,
-                                    int copy_size,
-                                    FixedArrayBase* source = NULL) = 0;
-
-  MaybeObject* CopyElements(JSObject* from_holder,
-                            FixedArrayBase* to,
-                            ElementsKind to_kind,
-                            FixedArrayBase* from = NULL) {
+  MUST_USE_RESULT virtual MaybeObject* CopyElements(
+      JSObject* source_holder,
+      uint32_t source_start,
+      FixedArrayBase* destination,
+      ElementsKind destination_kind,
+      uint32_t destination_start,
+      int copy_size,
+      FixedArrayBase* source = NULL) = 0;
+
+  MUST_USE_RESULT MaybeObject* CopyElements(JSObject* from_holder,
+                                            FixedArrayBase* to,
+                                            ElementsKind to_kind,
+                                            FixedArrayBase* from = NULL) {
     return CopyElements(from_holder, 0, to, to_kind, 0,
                         kCopyToEndAndInitializeToHole, from);
   }
 
-  virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
-                                               JSObject* holder,
-                                               FixedArray* to,
-                                               FixedArrayBase* from = NULL) = 0;
+  MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
+      Object* receiver,
+      JSObject* holder,
+      FixedArray* to,
+      FixedArrayBase* from = NULL) = 0;
 
   // Returns a shared ElementsAccessor for the specified ElementsKind.
   static ElementsAccessor* ForKind(ElementsKind elements_kind) {
@@ -131,6 +134,7 @@ class ElementsAccessor {
   static ElementsAccessor* ForArray(FixedArrayBase* array);
 
   static void InitializeOncePerProcess();
+  static void TearDown();
 
  protected:
   friend class NonStrictArgumentsElementsAccessor;
index 9fbf329..50d8761 100644 (file)
@@ -133,11 +133,8 @@ v8::Handle<v8::Value> ExternalizeStringExtension::IsAscii(
 
 
 void ExternalizeStringExtension::Register() {
-  static ExternalizeStringExtension* externalize_extension = NULL;
-  if (externalize_extension == NULL)
-    externalize_extension = new ExternalizeStringExtension;
-  static v8::DeclareExtension externalize_extension_declaration(
-      externalize_extension);
+  static ExternalizeStringExtension externalize_extension;
+  static v8::DeclareExtension declaration(&externalize_extension);
 }
 
 } }  // namespace v8::internal
index 573797e..f921552 100644 (file)
@@ -46,9 +46,8 @@ v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
 
 
 void GCExtension::Register() {
-  static GCExtension* gc_extension = NULL;
-  if (gc_extension == NULL) gc_extension = new GCExtension();
-  static v8::DeclareExtension gc_extension_declaration(gc_extension);
+  static GCExtension gc_extension;
+  static v8::DeclareExtension declaration(&gc_extension);
 }
 
 } }  // namespace v8::internal
index 143099c..6bb7893 100644 (file)
@@ -291,6 +291,15 @@ 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(
@@ -324,10 +333,9 @@ 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,
@@ -537,6 +545,10 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
           : isolate()->strict_mode_function_map(),
       pretenure);
 
+  if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
+    function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
+  }
+
   result->set_context(*context);
   if (!function_info->bound()) {
     int number_of_literals = function_info->num_literals();
@@ -924,6 +936,13 @@ 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(),
index 786d4a9..06aad1b 100644 (file)
@@ -162,9 +162,12 @@ 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,
@@ -177,7 +180,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);
@@ -262,6 +265,9 @@ 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,
index 75697a8..62a9782 100644 (file)
@@ -132,6 +132,8 @@ 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")
@@ -165,7 +167,12 @@ 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_bool(limit_inlining, true, "limit code size growth from 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(loop_invariant_code_motion, true, "loop invariant code motion")
 DEFINE_bool(collect_megamorphic_maps_from_stub_cache,
             true,
@@ -188,6 +195,8 @@ 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")
index 0571a81..e265341 100644 (file)
@@ -1359,34 +1359,28 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
 // -------------------------------------------------------------------------
 
 int NumRegs(RegList reglist) {
-  int n = 0;
-  while (reglist != 0) {
-    n++;
-    reglist &= reglist - 1;  // clear one bit
-  }
-  return n;
+  return CompilerIntrinsics::CountSetBits(reglist);
 }
 
 
 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;
 
-static LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data =
-    LAZY_INSTANCE_INITIALIZER;
+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);
+}
 
 int JSCallerSavedCode(int n) {
   ASSERT(0 <= n && n < kNumJSCallerSaved);
-  return caller_saved_code_data.Get().reg_code[n];
+  return caller_saved_code_data.reg_code[n];
 }
 
 
index 9071555..78cdd0c 100644 (file)
@@ -40,6 +40,8 @@ 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);
 
@@ -209,6 +211,9 @@ class StackFrame BASE_EMBEDDED {
 
   virtual void SetCallerFp(Address caller_fp) = 0;
 
+  // Manually changes value of fp in this object.
+  void UpdateFp(Address fp) { state_.fp = fp; }
+
   Address* pc_address() const { return state_.pc_address; }
 
   // Get the id of this stack frame.
index d963979..b8794c0 100644 (file)
@@ -315,7 +315,6 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
   Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
   code->set_optimizable(info->IsOptimizable() &&
                         !info->function()->flags()->Contains(kDontOptimize));
-  code->set_self_optimization_header(cgen.has_self_optimization_header_);
   cgen.PopulateDeoptimizationData(code);
   cgen.PopulateTypeFeedbackInfo(code);
   cgen.PopulateTypeFeedbackCells(code);
@@ -327,12 +326,10 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
   code->set_compiled_optimizable(info->IsOptimizable());
 #endif  // ENABLE_DEBUGGER_SUPPORT
   code->set_allow_osr_at_loop_nesting_level(0);
+  code->set_profiler_ticks(0);
   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 =
@@ -571,88 +568,91 @@ void FullCodeGenerator::DoTest(const TestContext* context) {
 
 void FullCodeGenerator::VisitDeclarations(
     ZoneList<Declaration*>* declarations) {
-  int save_global_count = global_count_;
-  global_count_ = 0;
+  ZoneList<Handle<Object> >* saved_globals = globals_;
+  ZoneList<Handle<Object> > inner_globals(10);
+  globals_ = &inner_globals;
 
   AstVisitor::VisitDeclarations(declarations);
-
-  // 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);
-        }
-      }
-    }
+  if (!globals_->is_empty()) {
     // 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);
   }
 
-  global_count_ = save_global_count;
-}
-
-
-void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
-  EmitDeclaration(decl->proxy(), decl->mode(), NULL);
+  globals_ = saved_globals;
 }
 
 
-void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
-  EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
-}
-
-
-void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) {
-  EmitDeclaration(decl->proxy(), decl->mode(), NULL);
-}
-
-
-void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
-  EmitDeclaration(decl->proxy(), decl->mode(), NULL);
-}
+void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
+  Handle<JSModule> instance = module->interface()->Instance();
+  ASSERT(!instance.is_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());
+  }
 
-void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
-  // TODO(rossberg)
-}
+  {
+    Comment cmnt(masm_, "[ Declarations");
+    VisitDeclarations(scope_->declarations());
+  }
 
+  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());
+  }
 
-void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
-  // TODO(rossberg)
+  // 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::VisitModuleVariable(ModuleVariable* module) {
-  // TODO(rossberg)
+  // Noting to do.
+  // The instance object is resolved statically through the module's interface.
 }
 
 
 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
-  // TODO(rossberg)
+  // Noting to do.
+  // The instance object is resolved statically through the module's interface.
 }
 
 
@@ -914,9 +914,9 @@ void FullCodeGenerator::VisitBlock(Block* stmt) {
 
   Scope* saved_scope = scope();
   // Push a block context when entering a block with block scoped variables.
-  if (stmt->block_scope() != NULL) {
+  if (stmt->scope() != NULL) {
     { Comment cmnt(masm_, "[ Extend block context");
-      scope_ = stmt->block_scope();
+      scope_ = stmt->scope();
       Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
       int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
       __ Push(scope_info);
@@ -943,7 +943,7 @@ void FullCodeGenerator::VisitBlock(Block* stmt) {
   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
 
   // Pop block context if necessary.
-  if (stmt->block_scope() != NULL) {
+  if (stmt->scope() != NULL) {
     LoadContextField(context_register(), Context::PREVIOUS_INDEX);
     // Update local stack frame context field.
     StoreToFrameField(StandardFrameConstants::kContextOffset,
index 58d5986..0e0ffe9 100644 (file)
@@ -83,22 +83,17 @@ class FullCodeGenerator: public AstVisitor {
         scope_(info->scope()),
         nesting_stack_(NULL),
         loop_depth_(0),
-        global_count_(0),
+        globals_(NULL),
         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),
-        has_self_optimization_header_(false) { }
+        ic_total_count_(0) { }
 
   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> { };
@@ -207,7 +202,7 @@ class FullCodeGenerator: public AstVisitor {
     virtual ~NestedBlock() {}
 
     virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
-      if (statement()->AsBlock()->block_scope() != NULL) {
+      if (statement()->AsBlock()->scope() != NULL) {
         ++(*context_length);
       }
       return previous_;
@@ -418,12 +413,9 @@ class FullCodeGenerator: public AstVisitor {
                                     Label* if_true,
                                     Label* if_false);
 
-  // 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);
+  // 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 checking the stack limit at the back edge of
   // a loop.
@@ -553,12 +545,8 @@ 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_; }
 
@@ -790,13 +778,12 @@ class FullCodeGenerator: public AstVisitor {
   Label return_label_;
   NestedStatement* nesting_stack_;
   int loop_depth_;
-  int global_count_;
+  ZoneList<Handle<Object> >* globals_;
   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_;
 
index 416ecbd..def1604 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -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->IsDontEnum(i)) {
+      if (descs->IsProperty(i) && !descs->GetDetails(i).IsDontEnum()) {
         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) {
index 5aeb895..91843b8 100644 (file)
@@ -63,7 +63,9 @@ class TemplateHashMapImpl {
   Entry* Lookup(void* key, uint32_t hash, bool insert);
 
   // Removes the entry with matching key.
-  void Remove(void* key, uint32_t hash);
+  // 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);
 
   // Empties the hash map (occupancy() == 0).
   void Clear();
@@ -146,14 +148,15 @@ 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;
+    return NULL;
   }
 
+  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
@@ -202,6 +205,7 @@ void TemplateHashMapImpl<P>::Remove(void* key, uint32_t hash) {
   // Clear the entry which is allowed to en emptied.
   p->key = NULL;
   occupancy_--;
+  return value;
 }
 
 
index 706d288..e12895a 100644 (file)
@@ -460,15 +460,16 @@ MaybeObject* Heap::PrepareForCompare(String* str) {
 }
 
 
-int Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
+intptr_t Heap::AdjustAmountOfExternalAllocatedMemory(
+    intptr_t change_in_bytes) {
   ASSERT(HasBeenSetUp());
-  int amount = amount_of_external_allocated_memory_ + change_in_bytes;
+  intptr_t amount = amount_of_external_allocated_memory_ + change_in_bytes;
   if (change_in_bytes >= 0) {
     // Avoid overflow.
     if (amount > amount_of_external_allocated_memory_) {
       amount_of_external_allocated_memory_ = amount;
     }
-    int amount_since_last_global_gc =
+    intptr_t amount_since_last_global_gc =
         amount_of_external_allocated_memory_ -
         amount_of_external_allocated_memory_at_last_global_gc_;
     if (amount_since_last_global_gc > external_allocation_limit_) {
index 8be6f27..2e971a5 100644 (file)
@@ -33,7 +33,6 @@
 namespace v8 {
 namespace internal {
 
-
 HeapProfiler::HeapProfiler()
     : snapshots_(new HeapSnapshotsCollection()),
       next_snapshot_uid_(1) {
@@ -86,6 +85,24 @@ 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);
@@ -136,6 +153,20 @@ 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();
@@ -158,6 +189,15 @@ 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);
index ef5c4f4..96b042d 100644 (file)
@@ -44,8 +44,6 @@ 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();
@@ -57,9 +55,14 @@ 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);
@@ -84,6 +87,10 @@ 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_;
index a1cccf6..d3c7f0a 100644 (file)
@@ -42,6 +42,7 @@
 #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"
@@ -60,8 +61,6 @@
 namespace v8 {
 namespace internal {
 
-static LazyMutex gc_initializer_mutex = LAZY_MUTEX_INITIALIZER;
-
 
 Heap::Heap()
     : isolate_(NULL),
@@ -145,7 +144,6 @@ Heap::Heap()
       number_idle_notifications_(0),
       last_idle_notification_gc_count_(0),
       last_idle_notification_gc_count_init_(false),
-      idle_notification_will_schedule_next_gc_(false),
       mark_sweeps_since_idle_round_started_(0),
       ms_count_at_last_idle_notification_(0),
       gc_count_at_last_idle_gc_(0),
@@ -173,6 +171,9 @@ Heap::Heap()
   global_contexts_list_ = NULL;
   mark_compact_collector_.heap_ = this;
   external_string_table_.heap_ = this;
+  // Put a dummy entry in the remembered pages so we can find the list the
+  // minidump even if there are no real unmapped pages.
+  RememberUnmappedPage(NULL, false);
 }
 
 
@@ -240,12 +241,17 @@ int Heap::GcSafeSizeOfOldObject(HeapObject* object) {
 GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
                                               const char** reason) {
   // Is global GC requested?
-  if (space != NEW_SPACE || FLAG_gc_global) {
+  if (space != NEW_SPACE) {
     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();
@@ -504,11 +510,17 @@ bool Heap::CollectGarbage(AllocationSpace space,
       !incremental_marking()->IsStopped() &&
       !incremental_marking()->should_hurry() &&
       FLAG_incremental_marking_steps) {
-    if (FLAG_trace_incremental_marking) {
-      PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
+    // Make progress in incremental marking.
+    const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB;
+    incremental_marking()->Step(kStepSizeWhenDelayedByScavenge,
+                                IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+    if (!incremental_marking()->IsComplete()) {
+      if (FLAG_trace_incremental_marking) {
+        PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
+      }
+      collector = SCAVENGER;
+      collector_reason = "incremental marking delaying mark-sweep";
     }
-    collector = SCAVENGER;
-    collector_reason = "incremental marking delaying mark-sweep";
   }
 
   bool next_gc_likely_to_collect_more = false;
@@ -796,7 +808,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
 
     UpdateSurvivalRateTrend(start_new_space_size);
 
-    size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize();
+    size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSizeOfObjects();
 
     if (high_survival_rate_during_scavenges &&
         IsStableOrIncreasingSurvivalTrend()) {
@@ -1120,6 +1132,27 @@ 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();
@@ -1218,6 +1251,9 @@ 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.
@@ -1304,7 +1340,8 @@ void Heap::UpdateReferencesInExternalStringTable(
 
 static Object* ProcessFunctionWeakReferences(Heap* heap,
                                              Object* function,
-                                             WeakObjectRetainer* retainer) {
+                                             WeakObjectRetainer* retainer,
+                                             bool record_slots) {
   Object* undefined = heap->undefined_value();
   Object* head = undefined;
   JSFunction* tail = NULL;
@@ -1321,6 +1358,12 @@ 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);
@@ -1349,6 +1392,15 @@ 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);
@@ -1364,6 +1416,14 @@ 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);
@@ -1376,11 +1436,19 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
           ProcessFunctionWeakReferences(
               this,
               candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST),
-              retainer);
+              retainer,
+              record_slots);
       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.
@@ -1480,6 +1548,27 @@ 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
@@ -1603,7 +1692,10 @@ class ScavengingVisitor : public StaticVisitorBase {
     }
   }
 
-  template<ObjectContents object_contents, SizeRestriction size_restriction>
+
+  template<ObjectContents object_contents,
+           SizeRestriction size_restriction,
+           int alignment>
   static inline void EvacuateObject(Map* map,
                                     HeapObject** slot,
                                     HeapObject* object,
@@ -1612,19 +1704,26 @@ 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) &&
-          (object_size > Page::kMaxNonCodeHeapObjectSize)) {
-        maybe_result = heap->lo_space()->AllocateRaw(object_size,
+          (allocation_size > Page::kMaxNonCodeHeapObjectSize)) {
+        maybe_result = heap->lo_space()->AllocateRaw(allocation_size,
                                                      NOT_EXECUTABLE);
       } else {
         if (object_contents == DATA_OBJECT) {
-          maybe_result = heap->old_data_space()->AllocateRaw(object_size);
+          maybe_result = heap->old_data_space()->AllocateRaw(allocation_size);
         } else {
-          maybe_result = heap->old_pointer_space()->AllocateRaw(object_size);
+          maybe_result =
+              heap->old_pointer_space()->AllocateRaw(allocation_size);
         }
       }
 
@@ -1632,6 +1731,10 @@ 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.
@@ -1639,18 +1742,27 @@ class ScavengingVisitor : public StaticVisitorBase {
         MigrateObject(heap, object, target, object_size);
 
         if (object_contents == POINTER_OBJECT) {
-          heap->promotion_queue()->insert(target, object_size);
+          if (map->instance_type() == JS_FUNCTION_TYPE) {
+            heap->promotion_queue()->insert(
+                target, JSFunction::kNonWeakFieldsEndOffset);
+          } else {
+            heap->promotion_queue()->insert(target, object_size);
+          }
         }
 
         heap->tracer()->increment_promoted_objects_size(object_size);
         return;
       }
     }
-    MaybeObject* allocation = heap->new_space()->AllocateRaw(object_size);
+    MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_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.
@@ -1686,7 +1798,7 @@ class ScavengingVisitor : public StaticVisitorBase {
                                         HeapObject** slot,
                                         HeapObject* object) {
     int object_size = FixedArray::BodyDescriptor::SizeOf(map, object);
-    EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map,
+    EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE, kObjectAlignment>(map,
                                                  slot,
                                                  object,
                                                  object_size);
@@ -1698,10 +1810,11 @@ class ScavengingVisitor : public StaticVisitorBase {
                                               HeapObject* object) {
     int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
     int object_size = FixedDoubleArray::SizeFor(length);
-    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map,
-                                              slot,
-                                              object,
-                                              object_size);
+    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kDoubleAlignment>(
+        map,
+        slot,
+        object,
+        object_size);
   }
 
 
@@ -1709,7 +1822,8 @@ class ScavengingVisitor : public StaticVisitorBase {
                                        HeapObject** slot,
                                        HeapObject* object) {
     int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize();
-    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size);
+    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>(
+        map, slot, object, object_size);
   }
 
 
@@ -1718,7 +1832,8 @@ class ScavengingVisitor : public StaticVisitorBase {
                                             HeapObject* object) {
     int object_size = SeqAsciiString::cast(object)->
         SeqAsciiStringSize(map->instance_type());
-    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size);
+    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>(
+        map, slot, object, object_size);
   }
 
 
@@ -1727,7 +1842,8 @@ class ScavengingVisitor : public StaticVisitorBase {
                                               HeapObject* object) {
     int object_size = SeqTwoByteString::cast(object)->
         SeqTwoByteStringSize(map->instance_type());
-    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size);
+    EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE, kObjectAlignment>(
+        map, slot, object, object_size);
   }
 
 
@@ -1770,7 +1886,8 @@ class ScavengingVisitor : public StaticVisitorBase {
     }
 
     int object_size = ConsString::kSize;
-    EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size);
+    EvacuateObject<POINTER_OBJECT, SMALL, kObjectAlignment>(
+        map, slot, object, object_size);
   }
 
   template<ObjectContents object_contents>
@@ -1780,14 +1897,16 @@ class ScavengingVisitor : public StaticVisitorBase {
     static inline void VisitSpecialized(Map* map,
                                         HeapObject** slot,
                                         HeapObject* object) {
-      EvacuateObject<object_contents, SMALL>(map, slot, object, object_size);
+      EvacuateObject<object_contents, SMALL, kObjectAlignment>(
+          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>(map, slot, object, object_size);
+      EvacuateObject<object_contents, SMALL, kObjectAlignment>(
+          map, slot, object, object_size);
     }
   };
 
@@ -1904,7 +2023,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
   map->set_pre_allocated_property_fields(0);
   map->init_instance_descriptors();
   map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
-  map->set_prototype_transitions(empty_fixed_array(), SKIP_WRITE_BARRIER);
+  map->init_prototype_transitions(undefined_value());
   map->set_unused_property_fields(0);
   map->set_bit_field(0);
   map->set_bit_field2(1 << Map::kIsExtensible);
@@ -1953,7 +2072,7 @@ MaybeObject* Heap::AllocateTypeFeedbackInfo() {
     if (!maybe_info->To(&info)) return maybe_info;
   }
   info->set_ic_total_count(0);
-  info->set_ic_with_typeinfo_count(0);
+  info->set_ic_with_type_info_count(0);
   info->set_type_feedback_cells(TypeFeedbackCells::cast(empty_fixed_array()),
                                 SKIP_WRITE_BARRIER);
   return info;
@@ -2043,15 +2162,15 @@ bool Heap::CreateInitialMaps() {
   // Fix the instance_descriptors for the existing maps.
   meta_map()->init_instance_descriptors();
   meta_map()->set_code_cache(empty_fixed_array());
-  meta_map()->set_prototype_transitions(empty_fixed_array());
+  meta_map()->init_prototype_transitions(undefined_value());
 
   fixed_array_map()->init_instance_descriptors();
   fixed_array_map()->set_code_cache(empty_fixed_array());
-  fixed_array_map()->set_prototype_transitions(empty_fixed_array());
+  fixed_array_map()->init_prototype_transitions(undefined_value());
 
   oddball_map()->init_instance_descriptors();
   oddball_map()->set_code_cache(empty_fixed_array());
-  oddball_map()->set_prototype_transitions(empty_fixed_array());
+  oddball_map()->init_prototype_transitions(undefined_value());
 
   // Fix prototype object for existing maps.
   meta_map()->set_prototype(null_value());
@@ -2897,9 +3016,9 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
   share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
   share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_this_property_assignments(undefined_value(), SKIP_WRITE_BARRIER);
-  share->set_deopt_counter(FLAG_deopt_every_n_times);
-  share->set_profiler_ticks(0);
   share->set_ast_node_count(0);
+  share->set_deopt_counter(FLAG_deopt_every_n_times);
+  share->set_ic_age(0);
 
   // Set integer fields (smi or int, depending on the architecture).
   share->set_length(0);
@@ -3823,6 +3942,16 @@ 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,
@@ -3959,7 +4088,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());
@@ -4652,6 +4781,11 @@ 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;
@@ -4664,7 +4798,12 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
   AllocationSpace retry_space =
       (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_DATA_SPACE : LO_SPACE;
 
-  return AllocateRaw(size, space, retry_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);
 }
 
 
@@ -4697,6 +4836,22 @@ 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;
@@ -4817,10 +4972,8 @@ void Heap::EnsureHeapIsIterable() {
 
 
 void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
-  // This flag prevents incremental marking from requesting GC via stack guard
-  idle_notification_will_schedule_next_gc_ = true;
-  incremental_marking()->Step(step_size);
-  idle_notification_will_schedule_next_gc_ = false;
+  incremental_marking()->Step(step_size,
+                              IncrementalMarking::NO_GC_VIA_STACK_GUARD);
 
   if (incremental_marking()->IsComplete()) {
     bool uncommit = false;
@@ -4841,8 +4994,10 @@ void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
 
 bool Heap::IdleNotification(int hint) {
   const int kMaxHint = 1000;
-  intptr_t size_factor = Min(Max(hint, 30), kMaxHint) / 10;
-  // The size factor is in range [3..100].
+  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 step_size = size_factor * IncrementalMarking::kAllocatedThreshold;
 
   if (contexts_disposed_ > 0) {
@@ -4866,11 +5021,14 @@ 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 (hint >= kMaxHint || !FLAG_incremental_marking ||
-      FLAG_expose_gc || Serializer::enabled()) {
+  if (!FLAG_incremental_marking || FLAG_expose_gc || Serializer::enabled()) {
     return IdleGlobalGC();
   }
 
@@ -4909,10 +5067,6 @@ bool Heap::IdleNotification(int hint) {
   }
 
   if (incremental_marking()->IsStopped()) {
-    if (!WorthStartingGCWhenIdle()) {
-      FinishIdleRound();
-      return true;
-    }
     incremental_marking()->Start();
   }
 
@@ -5550,6 +5704,11 @@ 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;
@@ -5654,16 +5813,6 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
 }
 
 
-intptr_t Heap::PromotedSpaceSize() {
-  return old_pointer_space_->Size()
-      + old_data_space_->Size()
-      + code_space_->Size()
-      + map_space_->Size()
-      + cell_space_->Size()
-      + lo_space_->Size();
-}
-
-
 intptr_t Heap::PromotedSpaceSizeOfObjects() {
   return old_pointer_space_->SizeOfObjects()
       + old_data_space_->SizeOfObjects()
@@ -5674,7 +5823,7 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() {
 }
 
 
-int Heap::PromotedExternalMemorySize() {
+intptr_t 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_
@@ -5847,6 +5996,15 @@ 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;
@@ -5865,15 +6023,7 @@ bool Heap::SetUp(bool create_heap_objects) {
     if (!ConfigureHeapDefault()) return false;
   }
 
-  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();
+  CallOnce(&initialize_gc_once, &InitializeGCOnce);
 
   MarkMapPointersAsEncoded(false);
 
@@ -5985,6 +6135,11 @@ 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_);
index 2bd037f..beb1bc5 100644 (file)
@@ -243,7 +243,8 @@ 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(hidden_stack_trace_symbol, "v8::hidden_stack_trace")                 \
+  V(query_colon_symbol, "(?:)")
 
 // Forward declarations.
 class GCTracer;
@@ -529,6 +530,8 @@ 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,
@@ -820,6 +823,10 @@ 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);
@@ -1326,7 +1333,8 @@ class Heap {
 
   // Adjusts the amount of registered external memory.
   // Returns the adjusted value.
-  inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
+  inline intptr_t AdjustAmountOfExternalAllocatedMemory(
+      intptr_t change_in_bytes);
 
   // Allocate uninitialized fixed array.
   MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length);
@@ -1334,7 +1342,7 @@ class Heap {
                                                      PretenureFlag pretenure);
 
   inline intptr_t PromotedTotalSize() {
-    return PromotedSpaceSize() + PromotedExternalMemorySize();
+    return PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize();
   }
 
   // True if we have reached the allocation limit in the old generation that
@@ -1355,19 +1363,6 @@ class Heap {
   static const intptr_t kMinimumAllocationLimit =
       8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
 
-  // When we sweep lazily we initially guess that there is no garbage on the
-  // heap and set the limits for the next GC accordingly.  As we sweep we find
-  // out that some of the pages contained garbage and we have to adjust
-  // downwards the size of the heap.  This means the limits that control the
-  // timing of the next GC also need to be adjusted downwards.
-  void LowerOldGenLimits(intptr_t adjustment) {
-    size_of_old_gen_at_last_old_space_gc_ -= adjustment;
-    old_gen_promotion_limit_ =
-        OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
-    old_gen_allocation_limit_ =
-        OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
-  }
-
   intptr_t OldGenPromotionLimit(intptr_t old_gen_size) {
     const int divisor = FLAG_stress_compaction ? 10 : 3;
     intptr_t limit =
@@ -1411,6 +1406,12 @@ 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(
@@ -1442,6 +1443,8 @@ 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 =
@@ -1452,7 +1455,7 @@ class Heap {
     intptr_t adjusted_allocation_limit =
         old_gen_allocation_limit_ - new_space_.Capacity() / 5;
 
-    if (PromotedSpaceSize() >= adjusted_allocation_limit) return true;
+    if (PromotedSpaceSizeOfObjects() >= adjusted_allocation_limit) return true;
 
     return false;
   }
@@ -1490,7 +1493,6 @@ class Heap {
   GCTracer* tracer() { return tracer_; }
 
   // Returns the size of objects residing in non new spaces.
-  intptr_t PromotedSpaceSize();
   intptr_t PromotedSpaceSizeOfObjects();
 
   double total_regexp_code_generated() { return total_regexp_code_generated_; }
@@ -1569,10 +1571,6 @@ class Heap {
   // The roots that have an index less than this are always in old space.
   static const int kOldSpaceRoots = 0x20;
 
-  bool idle_notification_will_schedule_next_gc() {
-    return idle_notification_will_schedule_next_gc_;
-  }
-
   uint32_t HashSeed() {
     uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
     ASSERT(FLAG_randomize_hashes || seed == 0);
@@ -1609,6 +1607,8 @@ 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_;
@@ -1650,7 +1650,7 @@ class Heap {
   int gc_post_processing_depth_;
 
   // Returns the amount of external memory registered since last global gc.
-  int PromotedExternalMemorySize();
+  intptr_t PromotedExternalMemorySize();
 
   int ms_count_;  // how many mark-sweep collections happened
   unsigned int gc_count_;  // how many gc happened
@@ -1715,17 +1715,15 @@ class Heap {
 
   // The amount of external memory registered through the API kept alive
   // by global handles
-  int amount_of_external_allocated_memory_;
+  intptr_t amount_of_external_allocated_memory_;
 
   // Caches the amount of external memory registered at the last global gc.
-  int amount_of_external_allocated_memory_at_last_global_gc_;
+  intptr_t 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_;
@@ -1978,13 +1976,6 @@ 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.
@@ -2033,7 +2024,6 @@ class Heap {
   unsigned int last_idle_notification_gc_count_;
   bool last_idle_notification_gc_count_init_;
 
-  bool idle_notification_will_schedule_next_gc_;
   int mark_sweeps_since_idle_round_started_;
   int ms_count_at_last_idle_notification_;
   unsigned int gc_count_at_last_idle_gc_;
index f698da4..c66a7a1 100644 (file)
@@ -416,6 +416,7 @@ 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();
@@ -462,7 +463,8 @@ void HValue::PrintChangesTo(StringStream* stream) {
       add_comma = true;                           \
       stream->Add(#type);                         \
     }
-    GVN_FLAG_LIST(PRINT_DO);
+    GVN_TRACKED_FLAG_LIST(PRINT_DO);
+    GVN_UNTRACKED_FLAG_LIST(PRINT_DO);
 #undef PRINT_DO
   }
   stream->Add("]");
@@ -599,6 +601,9 @@ void HInstruction::InsertAfter(HInstruction* previous) {
   SetBlock(block);
   previous->next_ = this;
   if (next != NULL) next->previous_ = this;
+  if (block->last() == previous) {
+    block->set_last(this);
+  }
 }
 
 
@@ -608,6 +613,7 @@ 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()) {
@@ -866,6 +872,17 @@ 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);
@@ -916,6 +933,62 @@ 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() &&
@@ -965,16 +1038,13 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
 }
 
 
-void HCheckMap::PrintDataTo(StringStream* stream) {
+void HCheckMaps::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
-  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(" [%p", *map_set()->first());
+  for (int i = 1; i < map_set()->length(); ++i) {
+    stream->Add(",%p", *map_set()->at(i));
   }
+  stream->Add("]");
 }
 
 
@@ -1533,6 +1603,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
   SetOperandAt(1, object);
   set_representation(Representation::Tagged());
   SetGVNFlag(kDependsOnMaps);
+  int map_transitions = 0;
   for (int i = 0;
        i < types->length() && types_.length() < kMaxLoadPolymorphism;
        ++i) {
@@ -1554,13 +1625,20 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
         case CONSTANT_FUNCTION:
           types_.Add(types->at(i));
           break;
+        case MAP_TRANSITION:
+          // We should just ignore these since they are not relevant to a load
+          // operation.  This means we will deopt if we actually see this map
+          // from optimized code.
+          map_transitions++;
+          break;
         default:
           break;
       }
     }
   }
 
-  if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) {
+  if (types_.length() + map_transitions == types->length() &&
+      FLAG_deoptimize_uncommon_cases) {
     SetFlag(kUseGVN);
   } else {
     SetAllSideEffects();
@@ -1736,6 +1814,9 @@ 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());
   }
@@ -1879,7 +1960,7 @@ HType HValue::CalculateInferredType() {
 }
 
 
-HType HCheckMap::CalculateInferredType() {
+HType HCheckMaps::CalculateInferredType() {
   return value()->type();
 }
 
@@ -2089,6 +2170,17 @@ 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())
@@ -2257,6 +2349,13 @@ 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;
index fb5879f..9d262fc 100644 (file)
@@ -85,7 +85,7 @@ class LChunkBuilder;
   V(Change)                                    \
   V(CheckFunction)                             \
   V(CheckInstanceType)                         \
-  V(CheckMap                                 \
+  V(CheckMaps)                                 \
   V(CheckNonSmi)                               \
   V(CheckPrototypeMaps)                        \
   V(CheckSmi)                                  \
@@ -140,6 +140,7 @@ class LChunkBuilder;
   V(LoadNamedField)                            \
   V(LoadNamedFieldPolymorphic)                 \
   V(LoadNamedGeneric)                          \
+  V(MathFloorOfDiv)                            \
   V(Mod)                                       \
   V(Mul)                                       \
   V(ObjectLiteral)                             \
@@ -188,7 +189,10 @@ class LChunkBuilder;
   V(DateField)                                 \
   V(WrapReceiver)
 
-#define GVN_FLAG_LIST(V)                       \
+#define GVN_TRACKED_FLAG_LIST(V)               \
+  V(NewSpacePromotion)
+
+#define GVN_UNTRACKED_FLAG_LIST(V)             \
   V(Calls)                                     \
   V(InobjectFields)                            \
   V(BackingStoreFields)                        \
@@ -506,14 +510,18 @@ 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.
+// flags. All tracked flags should appear before untracked ones.
 enum GVNFlag {
   // Declare global value numbering flags.
 #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
-  GVN_FLAG_LIST(DECLARE_FLAG)
+  GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
+  GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
 #undef DECLARE_FLAG
   kAfterLastFlag,
-  kLastFlag = kAfterLastFlag - 1
+  kLastFlag = kAfterLastFlag - 1,
+#define COUNT_FLAG(type) + 1
+  kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
+#undef COUNT_FLAG
 };
 
 typedef EnumSet<GVNFlag> GVNFlagSet;
@@ -530,6 +538,10 @@ 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,
@@ -544,6 +556,12 @@ 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);
   }
@@ -726,6 +744,13 @@ 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
@@ -756,7 +781,8 @@ class HValue: public ZoneObject {
     GVNFlagSet result;
     // Create changes mask.
 #define ADD_FLAG(type) result.Add(kDependsOn##type);
-  GVN_FLAG_LIST(ADD_FLAG)
+  GVN_TRACKED_FLAG_LIST(ADD_FLAG)
+  GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
 #undef ADD_FLAG
     return result;
   }
@@ -765,7 +791,8 @@ class HValue: public ZoneObject {
     GVNFlagSet result;
     // Create changes mask.
 #define ADD_FLAG(type) result.Add(kChanges##type);
-  GVN_FLAG_LIST(ADD_FLAG)
+  GVN_TRACKED_FLAG_LIST(ADD_FLAG)
+  GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
 #undef ADD_FLAG
     return result;
   }
@@ -781,6 +808,7 @@ 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);
@@ -1196,6 +1224,7 @@ 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);
@@ -1321,6 +1350,7 @@ class HStackCheck: public HTemplateInstruction<1> {
 
   HStackCheck(HValue* context, Type type) : type_(type) {
     SetOperandAt(0, context);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   HValue* context() { return OperandAt(0); }
@@ -1353,12 +1383,16 @@ class HEnterInlined: public HTemplateInstruction<0> {
                 int arguments_count,
                 FunctionLiteral* function,
                 CallKind call_kind,
-                bool is_construct)
+                bool is_construct,
+                Variable* arguments_var,
+                ZoneList<HValue*>* arguments_values)
       : closure_(closure),
         arguments_count_(arguments_count),
         function_(function),
         call_kind_(call_kind),
-        is_construct_(is_construct) {
+        is_construct_(is_construct),
+        arguments_var_(arguments_var),
+        arguments_values_(arguments_values) {
   }
 
   virtual void PrintDataTo(StringStream* stream);
@@ -1373,6 +1407,9 @@ class HEnterInlined: public HTemplateInstruction<0> {
     return Representation::None();
   }
 
+  Variable* arguments_var() { return arguments_var_; }
+  ZoneList<HValue*>* arguments_values() { return arguments_values_; }
+
   DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
 
  private:
@@ -1381,18 +1418,28 @@ class HEnterInlined: public HTemplateInstruction<0> {
   FunctionLiteral* function_;
   CallKind call_kind_;
   bool is_construct_;
+  Variable* arguments_var_;
+  ZoneList<HValue*>* arguments_values_;
 };
 
 
 class HLeaveInlined: public HTemplateInstruction<0> {
  public:
-  HLeaveInlined() {}
+  explicit HLeaveInlined(bool arguments_pushed)
+      : arguments_pushed_(arguments_pushed) { }
 
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
   }
 
+  bool arguments_pushed() {
+    return arguments_pushed_;
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
+
+ private:
+  bool arguments_pushed_;
 };
 
 
@@ -1600,14 +1647,26 @@ 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_;
 };
 
 
@@ -1860,6 +1919,8 @@ class HBitNot: public HUnaryOperation {
   }
   virtual HType CalculateInferredType();
 
+  virtual HValue* Canonicalize();
+
   DECLARE_CONCRETE_INSTRUCTION(BitNot)
 
  protected:
@@ -1882,6 +1943,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
       case kMathAbs:
         set_representation(Representation::Tagged());
         SetFlag(kFlexibleRepresentation);
+        SetGVNFlag(kChangesNewSpacePromotion);
         break;
       case kMathSqrt:
       case kMathPowHalf:
@@ -1890,6 +1952,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
       case kMathCos:
       case kMathTan:
         set_representation(Representation::Double());
+        SetGVNFlag(kChangesNewSpacePromotion);
         break;
       default:
         UNREACHABLE();
@@ -1930,15 +1993,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
     }
   }
 
-  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;
-  }
+  virtual HValue* Canonicalize();
 
   BuiltinFunctionId op() const { return op_; }
   const char* OpName() const;
@@ -1998,14 +2053,9 @@ class HLoadExternalArrayPointer: public HUnaryOperation {
 };
 
 
-class HCheckMap: public HTemplateInstruction<2> {
+class HCheckMaps: public HTemplateInstruction<2> {
  public:
-  HCheckMap(HValue* value,
-            Handle<Map> map,
-            HValue* typecheck = NULL,
-            CompareMapMode mode = REQUIRE_EXACT_MAP)
-      : map_(map),
-        mode_(mode) {
+  HCheckMaps(HValue* value, Handle<Map> map, HValue* typecheck = NULL) {
     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.
@@ -2013,14 +2063,49 @@ class HCheckMap: public HTemplateInstruction<2> {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
     SetGVNFlag(kDependsOnMaps);
-    // 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);
+    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));
+    }
+    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));
     }
-    has_element_transitions_ =
-        map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL ||
-        map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL;
+    map_set->Sort();
+
+    return check_map;
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -2030,25 +2115,23 @@ class HCheckMap: public HTemplateInstruction<2> {
   virtual HType CalculateInferredType();
 
   HValue* value() { return OperandAt(0); }
-  Handle<Map> map() const { return map_; }
-  CompareMapMode mode() const { return mode_; }
+  SmallMapList* map_set() { return &map_set_; }
 
-  DECLARE_CONCRETE_INSTRUCTION(CheckMap)
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
 
  protected:
   virtual bool DataEquals(HValue* other) {
-    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_);
+    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;
   }
 
  private:
-  bool has_element_transitions_;
-  Handle<Map> map_;
-  CompareMapMode mode_;
+  SmallMapList map_set_;
 };
 
 
@@ -2544,7 +2627,7 @@ class HApplyArguments: public HTemplateInstruction<4> {
 
 class HArgumentsElements: public HTemplateInstruction<0> {
  public:
-  HArgumentsElements() {
+  explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
     // 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());
@@ -2557,8 +2640,12 @@ 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_;
 };
 
 
@@ -2664,6 +2751,25 @@ 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)
@@ -3078,6 +3184,7 @@ class HPower: public HTemplateInstruction<2> {
     SetOperandAt(1, right);
     set_representation(Representation::Double());
     SetFlag(kUseGVN);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   HValue* left() { return OperandAt(0); }
@@ -3277,6 +3384,8 @@ class HBitwise: public HBitwiseBinaryOperation {
                                    HValue* left,
                                    HValue* right);
 
+  virtual void PrintDataTo(StringStream* stream);
+
   DECLARE_CONCRETE_INSTRUCTION(Bitwise)
 
  protected:
@@ -3524,6 +3633,12 @@ 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,
@@ -3990,9 +4105,12 @@ class HStoreNamedField: public HTemplateInstruction<2> {
                    int offset)
       : name_(name),
         is_in_object_(in_object),
-        offset_(offset) {
+        offset_(offset),
+        new_space_dominator_(NULL) {
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
+    SetFlag(kTrackSideEffectDominators);
+    SetGVNFlag(kDependsOnNewSpacePromotion);
     if (is_in_object_) {
       SetGVNFlag(kChangesInobjectFields);
     } else {
@@ -4005,6 +4123,10 @@ 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); }
@@ -4015,9 +4137,11 @@ 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());
+    return StoringValueNeedsWriteBarrier(value()) &&
+        ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
   }
 
  private:
@@ -4025,6 +4149,7 @@ class HStoreNamedField: public HTemplateInstruction<2> {
   bool is_in_object_;
   int offset_;
   Handle<Map> transition_;
+  HValue* new_space_dominator_;
 };
 
 
@@ -4134,6 +4259,8 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
     return StoringValueNeedsWriteBarrier(value());
   }
 
+  bool NeedsCanonicalization();
+
   virtual void PrintDataTo(StringStream* stream);
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
@@ -4227,6 +4354,7 @@ class HTransitionElementsKind: public HTemplateInstruction<1> {
     SetFlag(kUseGVN);
     SetGVNFlag(kChangesElementsKind);
     SetGVNFlag(kChangesElementsPointer);
+    SetGVNFlag(kChangesNewSpacePromotion);
     set_representation(Representation::Tagged());
   }
 
@@ -4288,6 +4416,7 @@ class HStringCharCodeAt: public HTemplateInstruction<3> {
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
     SetGVNFlag(kDependsOnMaps);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -4319,6 +4448,7 @@ class HStringCharFromCode: public HTemplateInstruction<2> {
     SetOperandAt(1, char_code);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -4371,8 +4501,12 @@ 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_; }
 
@@ -4416,6 +4550,7 @@ 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
@@ -4451,6 +4586,7 @@ class HArrayLiteral: public HMaterializedLiteral<1> {
         length_(length),
         boilerplate_object_(boilerplate_object) {
     SetOperandAt(0, context);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   HValue* context() { return OperandAt(0); }
@@ -4491,6 +4627,7 @@ class HObjectLiteral: public HMaterializedLiteral<1> {
         fast_elements_(fast_elements),
         has_function_(has_function) {
     SetOperandAt(0, context);
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   HValue* context() { return OperandAt(0); }
@@ -4552,6 +4689,7 @@ class HFunctionLiteral: public HTemplateInstruction<1> {
       : shared_info_(shared), pretenure_(pretenure) {
     SetOperandAt(0, context);
     set_representation(Representation::Tagged());
+    SetGVNFlag(kChangesNewSpacePromotion);
   }
 
   HValue* context() { return OperandAt(0); }
index 34fd1bc..3be001e 100644 (file)
@@ -113,7 +113,6 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
     first_ = last_ = entry;
   }
   instr->InsertAfter(last_);
-  last_ = instr;
 }
 
 
@@ -165,11 +164,15 @@ void HBasicBlock::Finish(HControlInstruction* end) {
 }
 
 
-void HBasicBlock::Goto(HBasicBlock* block, bool drop_extra) {
+void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) {
+  bool drop_extra = state != NULL && state->drop_extra();
+  bool arguments_pushed = state != NULL && state->arguments_pushed();
+
   if (block->IsInlineReturnTarget()) {
-    AddInstruction(new(zone()) HLeaveInlined);
+    AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
     last_environment_ = last_environment()->DiscardInlined(drop_extra);
   }
+
   AddSimulate(AstNode::kNoNumber);
   HGoto* instr = new(zone()) HGoto(block);
   Finish(instr);
@@ -178,10 +181,13 @@ void HBasicBlock::Goto(HBasicBlock* block, bool drop_extra) {
 
 void HBasicBlock::AddLeaveInlined(HValue* return_value,
                                   HBasicBlock* target,
-                                  bool drop_extra) {
+                                  FunctionState* state) {
+  bool drop_extra = state != NULL && state->drop_extra();
+  bool arguments_pushed = state != NULL && state->arguments_pushed();
+
   ASSERT(target->IsInlineReturnTarget());
   ASSERT(return_value != NULL);
-  AddInstruction(new(zone()) HLeaveInlined);
+  AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
   last_environment_ = last_environment()->DiscardInlined(drop_extra);
   last_environment()->Push(return_value);
   AddSimulate(AstNode::kNoNumber);
@@ -606,6 +612,7 @@ 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
@@ -1143,14 +1150,39 @@ void HRangeAnalysis::AddRange(HValue* value, Range* range) {
 
 
 void TraceGVN(const char* msg, ...) {
-  if (FLAG_trace_gvn) {
-    va_list arguments;
-    va_start(arguments, msg);
-    OS::VPrint(msg, arguments);
-    va_end(arguments);
-  }
+  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);          \
+  }
+
 
 HValueMap::HValueMap(Zone* zone, const HValueMap* other)
     : array_size_(other->array_size_),
@@ -1321,6 +1353,38 @@ 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) { }
@@ -1427,7 +1491,9 @@ class HGlobalValueNumberer BASE_EMBEDDED {
   GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
       HBasicBlock* dominator,
       HBasicBlock* dominated);
-  void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
+  void AnalyzeBlock(HBasicBlock* block,
+                    HValueMap* map,
+                    HSideEffectMap* dominators);
   void ComputeBlockSideEffects();
   void LoopInvariantCodeMotion();
   void ProcessLoopBlock(HBasicBlock* block,
@@ -1465,7 +1531,8 @@ bool HGlobalValueNumberer::Analyze() {
     LoopInvariantCodeMotion();
   }
   HValueMap* map = new(zone()) HValueMap();
-  AnalyzeBlock(graph_->entry_block(), map);
+  HSideEffectMap side_effect_dominators;
+  AnalyzeBlock(graph_->entry_block(), map, &side_effect_dominators);
   return removed_side_effects_;
 }
 
@@ -1510,14 +1577,100 @@ 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()];
-      TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n",
-               block->block_id(),
-               side_effects.ToIntegral());
+      TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
+                  block->block_id(),
+                  *GetGVNFlagsString(side_effects));
 
       GVNFlagSet accumulated_first_time_depends;
       GVNFlagSet accumulated_first_time_changes;
@@ -1540,20 +1693,19 @@ void HGlobalValueNumberer::ProcessLoopBlock(
     GVNFlagSet* first_time_changes) {
   HBasicBlock* pre_header = loop_header->predecessors()->at(0);
   GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
-  TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n",
-           block->block_id(),
-           depends_flags.ToIntegral());
+  TRACE_GVN_2("Loop invariant motion for B%d %s\n",
+              block->block_id(),
+              *GetGVNFlagsString(depends_flags));
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
     bool hoisted = false;
     if (instr->CheckFlag(HValue::kUseGVN)) {
-      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());
+      TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n",
+                  instr->id(),
+                  instr->Mnemonic(),
+                  *GetGVNFlagsString(instr->gvn_flags()),
+                  *GetGVNFlagsString(loop_kills));
       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
@@ -1576,15 +1728,19 @@ void HGlobalValueNumberer::ProcessLoopBlock(
         if (trans->transitioned_map()->has_fast_double_elements()) {
           hoist_change_blockers.Add(kChangesArrayElements);
         }
-        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());
+        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));
+        }
         // 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
@@ -1607,7 +1763,7 @@ void HGlobalValueNumberer::ProcessLoopBlock(
         }
 
         if (inputs_loop_invariant && ShouldMove(instr, loop_header)) {
-          TraceGVN("Hoisting loop invariant instruction %d\n", instr->id());
+          TRACE_GVN_1("Hoisting loop invariant instruction %d\n", instr->id());
           // Move the instruction out of the loop.
           instr->Unlink();
           instr->InsertBefore(pre_header->end());
@@ -1619,8 +1775,18 @@ 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;
   }
@@ -1660,10 +1826,12 @@ GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
 }
 
 
-void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
-  TraceGVN("Analyzing block B%d%s\n",
-           block->block_id(),
-           block->IsLoopHeader() ? " (loop header)" : "");
+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)" : "");
 
   // If this is a loop header kill everything killed by the loop.
   if (block->IsLoopHeader()) {
@@ -1677,25 +1845,45 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
     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);
-      TraceGVN("Instruction %d kills\n", instr->id());
+      dominators->Store(flags, instr);
+      TRACE_GVN_2("Instruction %d %s\n", instr->id(),
+                  *GetGVNFlagsString(flags));
     }
     if (instr->CheckFlag(HValue::kUseGVN)) {
       ASSERT(!instr->HasObservableSideEffects());
       HValue* other = map->Lookup(instr);
       if (other != NULL) {
         ASSERT(instr->Equals(other) && other->Equals(instr));
-        TraceGVN("Replacing value %d (%s) with value %d (%s)\n",
-                 instr->id(),
-                 instr->Mnemonic(),
-                 other->id(),
-                 other->Mnemonic());
+        TRACE_GVN_4("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;
   }
 
@@ -1705,20 +1893,22 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
     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 is
-    // already empty.
-    // If the range of block ids (block_id, dominated_id) is empty
-    // there are no such paths.
-    if (!successor_map->IsEmpty() &&
+    // 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()) &&
         block->block_id() + 1 < dominated->block_id()) {
       visited_on_paths_.Clear();
-      successor_map->Kill(CollectSideEffectsOnPathsToDominatedBlock(block,
-                                                                    dominated));
+      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);
     }
-    AnalyzeBlock(dominated, successor_map);
+    AnalyzeBlock(dominated, successor_map, &successor_dominators);
   }
 }
 
@@ -2178,6 +2368,8 @@ 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.
@@ -2337,8 +2529,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()->drop_extra());
-  empty_false->Goto(if_false(), owner()->function_state()->drop_extra());
+  empty_true->Goto(if_true(), owner()->function_state());
+  empty_false->Goto(if_false(), owner()->function_state());
   owner()->set_current_block(NULL);
 }
 
@@ -2359,8 +2551,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()->drop_extra());
-  empty_false->Goto(if_false(), owner()->function_state()->drop_extra());
+  empty_true->Goto(if_true(), owner()->function_state());
+  empty_false->Goto(if_false(), owner()->function_state());
   builder->set_current_block(NULL);
 }
 
@@ -2484,7 +2676,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) {
-      HandleDeclaration(scope->function(), CONST, NULL, NULL);
+      VisitVariableDeclaration(scope->function());
     }
     VisitDeclarations(scope->declarations());
     AddSimulate(AstNode::kDeclarationsId);
@@ -2565,29 +2757,328 @@ HGraph* HGraphBuilder::CreateGraph() {
   HStackCheckEliminator sce(graph());
   sce.Process();
 
-  // 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();
+  graph()->EliminateRedundantBoundsChecks();
 
   return graph();
 }
 
 
-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());
+// 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();
       }
-      instr = instr->next();
+    } 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();
+      }
+    }
+
+    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());
+    }
+  }
+}
+
+
+void HGraph::EliminateRedundantBoundsChecks() {
+  HPhase phase("H_Eliminate bounds checks", this);
+  AssertNoAllocation no_gc;
+  BoundsCheckTable checks_table;
+  EliminateRedundantBoundsChecks(entry_block(), &checks_table);
 }
 
 
@@ -2701,7 +3192,7 @@ void HGraphBuilder::VisitBlock(Block* stmt) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
-  if (stmt->block_scope() != NULL) {
+  if (stmt->scope() != NULL) {
     return Bailout("ScopedBlock");
   }
   BreakAndContinueInfo break_info(stmt);
@@ -2855,10 +3346,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()->drop_extra());
+      current_block()->Goto(test->if_true(), function_state());
     } else if (context->IsEffect()) {
       CHECK_ALIVE(VisitForEffect(stmt->expression()));
-      current_block()->Goto(function_return(), function_state()->drop_extra());
+      current_block()->Goto(function_return(), function_state());
     } else {
       ASSERT(context->IsValue());
       CHECK_ALIVE(VisitForValue(stmt->expression()));
@@ -2875,10 +3366,10 @@ void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
       current_block()->Finish(typecheck);
       if_spec_object->AddLeaveInlined(return_value,
                                       function_return(),
-                                      function_state()->drop_extra());
+                                      function_state());
       not_spec_object->AddLeaveInlined(receiver,
                                        function_return(),
-                                       function_state()->drop_extra());
+                                       function_state());
     }
   } else {
     // Return from an inlined function, visit the subexpression in the
@@ -2890,14 +3381,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()->drop_extra());
+      current_block()->Goto(function_return(), function_state());
     } else {
       ASSERT(context->IsValue());
       CHECK_ALIVE(VisitForValue(stmt->expression()));
       HValue* return_value = Pop();
       current_block()->AddLeaveInlined(return_value,
                                        function_return(),
-                                       function_state()->drop_extra());
+                                       function_state());
     }
   }
   set_current_block(NULL);
@@ -3682,10 +4173,11 @@ 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 = JSObject::GetElement(boilerplate, i);
+        Handle<Object> value(fast_elements->get(i));
         if (value->IsJSObject()) {
           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
           if (!IsFastLiteral(value_object,
@@ -3914,21 +4406,22 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
 }
 
 
-// Sets the lookup result and returns true if the store can be inlined.
-static bool ComputeStoredField(Handle<Map> type,
-                               Handle<String> name,
-                               LookupResult* lookup) {
+// 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) {
   type->LookupInDescriptors(NULL, *name, lookup);
   if (!lookup->IsFound()) return false;
   if (lookup->type() == FIELD) return true;
-  return (lookup->type() == MAP_TRANSITION) &&
+  return is_store && (lookup->type() == MAP_TRANSITION) &&
       (type->unused_property_fields() > 0);
 }
 
 
-static int ComputeStoredFieldIndex(Handle<Map> type,
-                                   Handle<String> name,
-                                   LookupResult* lookup) {
+static int ComputeLoadStoreFieldIndex(Handle<Map> type,
+                                      Handle<String> name,
+                                      LookupResult* lookup) {
   ASSERT(lookup->type() == FIELD || lookup->type() == MAP_TRANSITION);
   if (lookup->type() == FIELD) {
     return lookup->GetLocalFieldIndexFromMap(*type);
@@ -3947,11 +4440,10 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
                                                   bool smi_and_map_check) {
   if (smi_and_map_check) {
     AddInstruction(new(zone()) HCheckNonSmi(object));
-    AddInstruction(new(zone()) HCheckMap(object, type, NULL,
-                                         ALLOW_ELEMENT_TRANSITION_MAPS));
+    AddInstruction(HCheckMaps::NewWithTransitions(object, type));
   }
 
-  int index = ComputeStoredFieldIndex(type, name, lookup);
+  int index = ComputeLoadStoreFieldIndex(type, name, lookup);
   bool is_in_object = index < 0;
   int offset = index * kPointerSize;
   if (index < 0) {
@@ -3997,7 +4489,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
   LookupResult lookup(isolate());
   Handle<Map> type = prop->GetReceiverType();
   bool is_monomorphic = prop->IsMonomorphic() &&
-      ComputeStoredField(type, name, &lookup);
+      ComputeLoadStoreField(type, name, &lookup, true);
 
   return is_monomorphic
       ? BuildStoreNamedField(object, name, value, type, &lookup,
@@ -4019,7 +4511,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
   LookupResult lookup(isolate());
   SmallMapList* types = expr->GetReceiverTypes();
   bool is_monomorphic = expr->IsMonomorphic() &&
-      ComputeStoredField(types->first(), name, &lookup);
+      ComputeLoadStoreField(types->first(), name, &lookup, true);
 
   return is_monomorphic
       ? BuildStoreNamedField(object, name, value, types->first(), &lookup,
@@ -4028,6 +4520,59 @@ 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,
@@ -4041,7 +4586,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 (ComputeStoredField(map, name, &lookup)) {
+    if (ComputeLoadStoreField(map, name, &lookup, true)) {
       if (count == 0) {
         AddInstruction(new(zone()) HCheckNonSmi(object));  // Only needed once.
         join = graph()->CreateBasicBlock();
@@ -4512,8 +5057,7 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
                                                     bool smi_and_map_check) {
   if (smi_and_map_check) {
     AddInstruction(new(zone()) HCheckNonSmi(object));
-    AddInstruction(new(zone()) HCheckMap(object, type, NULL,
-                                         ALLOW_ELEMENT_TRANSITION_MAPS));
+    AddInstruction(HCheckMaps::NewWithTransitions(object, type));
   }
 
   int index = lookup->GetLocalFieldIndexFromMap(*type);
@@ -4557,8 +5101,7 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj,
                                true);
   } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
     AddInstruction(new(zone()) HCheckNonSmi(obj));
-    AddInstruction(new(zone()) HCheckMap(obj, map, NULL,
-                                         ALLOW_ELEMENT_TRANSITION_MAPS));
+    AddInstruction(HCheckMaps::NewWithTransitions(obj, map));
     Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
     return new(zone()) HConstant(function, Representation::Tagged());
   } else {
@@ -4660,12 +5203,12 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
                                                            HValue* val,
                                                            Handle<Map> map,
                                                            bool is_store) {
-  HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map));
+  HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMaps(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()) HCheckMap(
+    AddInstruction(new(zone()) HCheckMaps(
         elements, isolate()->factory()->fixed_array_map()));
   }
   HInstruction* length = NULL;
@@ -4815,7 +5358,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()) HCheckMap(
+          AddInstruction(new(zone()) HCheckMaps(
               elements, isolate()->factory()->fixed_array_map(),
               elements_kind_branch));
         }
@@ -4933,6 +5476,34 @@ 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;
@@ -4941,31 +5512,51 @@ 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;
-    HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
-    result = new(zone()) HArgumentsLength(elements);
+
+    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());
+    }
   } else {
     Push(graph()->GetArgumentsObject());
     VisitForValue(expr->key());
     if (HasStackOverflow() || current_block() == NULL) return true;
     HValue* key = Pop();
     Drop(1);  // Arguments object.
-    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);
+    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);
+    }
   }
   ast_context()->ReturnInstruction(result, expr->id());
   return true;
@@ -5019,8 +5610,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));
-      HValue* context = environment()->LookupContext();
-      instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name);
+      HandlePolymorphicLoadNamedField(expr, obj, types, name);
+      return;
     } else {
       instr = BuildLoadNamedGeneric(obj, expr);
     }
@@ -5061,8 +5652,7 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
   // its prototypes.
   if (smi_and_map_check) {
     AddInstruction(new(zone()) HCheckNonSmi(receiver));
-    AddInstruction(new(zone()) HCheckMap(receiver, receiver_map, NULL,
-                                         ALLOW_ELEMENT_TRANSITION_MAPS));
+    AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map));
   }
   if (!expr->holder().is_null()) {
     AddInstruction(new(zone()) HCheckPrototypeMaps(
@@ -5072,6 +5662,39 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
 }
 
 
+class FunctionSorter {
+ public:
+  FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
+  FunctionSorter(int index, int ticks, int ast_length, int src_length)
+      : index_(index),
+        ticks_(ticks),
+        ast_length_(ast_length),
+        src_length_(src_length) { }
+
+  int index() const { return index_; }
+  int ticks() const { return ticks_; }
+  int ast_length() const { return ast_length_; }
+  int src_length() const { return src_length_; }
+
+ private:
+  int index_;
+  int ticks_;
+  int ast_length_;
+  int src_length_;
+};
+
+
+static int CompareHotness(void const* a, void const* b) {
+  FunctionSorter const* function1 = reinterpret_cast<FunctionSorter const*>(a);
+  FunctionSorter const* function2 = reinterpret_cast<FunctionSorter const*>(b);
+  int diff = function1->ticks() - function2->ticks();
+  if (diff != 0) return -diff;
+  diff = function1->ast_length() - function2->ast_length();
+  if (diff != 0) return diff;
+  return function1->src_length() - function2->src_length();
+}
+
+
 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
                                                HValue* receiver,
                                                SmallMapList* types,
@@ -5080,51 +5703,73 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
   // maps are identical. In that case we can avoid repeatedly generating the
   // same prototype map checks.
   int argument_count = expr->arguments()->length() + 1;  // Includes receiver.
-  int count = 0;
   HBasicBlock* join = NULL;
-  for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) {
+  FunctionSorter order[kMaxCallPolymorphism];
+  int ordered_functions = 0;
+  for (int i = 0;
+       i < types->length() && ordered_functions < kMaxCallPolymorphism;
+       ++i) {
     Handle<Map> map = types->at(i);
     if (expr->ComputeTarget(map, name)) {
-      if (count == 0) {
-        // Only needed once.
-        AddInstruction(new(zone()) HCheckNonSmi(receiver));
-        join = graph()->CreateBasicBlock();
-      }
-      ++count;
-      HBasicBlock* if_true = graph()->CreateBasicBlock();
-      HBasicBlock* if_false = graph()->CreateBasicBlock();
-      HCompareMap* compare =
-          new(zone()) HCompareMap(receiver, map, if_true, if_false);
-      current_block()->Finish(compare);
+      order[ordered_functions++] =
+          FunctionSorter(i,
+                         expr->target()->shared()->profiler_ticks(),
+                         InliningAstSize(expr->target()),
+                         expr->target()->shared()->SourceSize());
+    }
+  }
 
-      set_current_block(if_true);
-      AddCheckConstantFunction(expr, receiver, map, false);
-      if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
-        PrintF("Trying to inline the polymorphic call to %s\n",
-               *name->ToCString());
-      }
-      if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
-        // Trying to inline will signal that we should bailout from the
-        // entire compilation by setting stack overflow on the visitor.
-        if (HasStackOverflow()) return;
-      } else {
-        HCallConstantFunction* call =
-            new(zone()) HCallConstantFunction(expr->target(), argument_count);
-        call->set_position(expr->position());
-        PreProcessCall(call);
-        AddInstruction(call);
-        if (!ast_context()->IsEffect()) Push(call);
-      }
+  qsort(reinterpret_cast<void*>(&order[0]),
+        ordered_functions,
+        sizeof(order[0]),
+        &CompareHotness);
 
-      if (current_block() != NULL) current_block()->Goto(join);
-      set_current_block(if_false);
+  for (int fn = 0; fn < ordered_functions; ++fn) {
+    int i = order[fn].index();
+    Handle<Map> map = types->at(i);
+    if (fn == 0) {
+      // Only needed once.
+      AddInstruction(new(zone()) HCheckNonSmi(receiver));
+      join = graph()->CreateBasicBlock();
+    }
+    HBasicBlock* if_true = graph()->CreateBasicBlock();
+    HBasicBlock* if_false = graph()->CreateBasicBlock();
+    HCompareMap* compare =
+        new(zone()) HCompareMap(receiver, map, if_true, if_false);
+    current_block()->Finish(compare);
+
+    set_current_block(if_true);
+    expr->ComputeTarget(map, name);
+    AddCheckConstantFunction(expr, receiver, map, false);
+    if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
+      Handle<JSFunction> caller = info()->closure();
+      SmartArrayPointer<char> caller_name =
+          caller->shared()->DebugName()->ToCString();
+      PrintF("Trying to inline the polymorphic call to %s from %s\n",
+             *name->ToCString(),
+             *caller_name);
+    }
+    if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
+      // Trying to inline will signal that we should bailout from the
+      // entire compilation by setting stack overflow on the visitor.
+      if (HasStackOverflow()) return;
+    } else {
+      HCallConstantFunction* call =
+          new(zone()) HCallConstantFunction(expr->target(), argument_count);
+      call->set_position(expr->position());
+      PreProcessCall(call);
+      AddInstruction(call);
+      if (!ast_context()->IsEffect()) Push(call);
     }
+
+    if (current_block() != NULL) current_block()->Goto(join);
+    set_current_block(if_false);
   }
 
   // Finish up.  Unconditionally deoptimize if we've handled all the maps we
   // know about and do not want to handle ones we've never seen.  Otherwise
   // use a generic IC.
-  if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
+  if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
     current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
   } else {
     HValue* context = environment()->LookupContext();
@@ -5173,14 +5818,11 @@ void HGraphBuilder::TraceInline(Handle<JSFunction> target,
 }
 
 
-bool HGraphBuilder::TryInline(CallKind call_kind,
-                              Handle<JSFunction> target,
-                              ZoneList<Expression*>* arguments,
-                              HValue* receiver,
-                              int ast_id,
-                              int return_id,
-                              ReturnHandlingFlag return_handling) {
-  if (!FLAG_use_inlining) return false;
+static const int kNotInlinable = 1000000000;
+
+
+int HGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
+  if (!FLAG_use_inlining) return kNotInlinable;
 
   // Precondition: call is monomorphic and we have found a target with the
   // appropriate arity.
@@ -5189,29 +5831,46 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
 
   // Do a quick check on source code length to avoid parsing large
   // inlining candidates.
-  if ((FLAG_limit_inlining && target_shared->SourceSize() > kMaxSourceSize)
-      || target_shared->SourceSize() > kUnlimitedMaxSourceSize) {
+  if (target_shared->SourceSize() >
+      Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) {
     TraceInline(target, caller, "target text too big");
-    return false;
+    return kNotInlinable;
   }
 
   // Target must be inlineable.
   if (!target->IsInlineable()) {
     TraceInline(target, caller, "target not inlineable");
-    return false;
+    return kNotInlinable;
   }
   if (target_shared->dont_inline() || target_shared->dont_optimize()) {
     TraceInline(target, caller, "target contains unsupported syntax [early]");
-    return false;
+    return kNotInlinable;
   }
 
   int nodes_added = target_shared->ast_node_count();
-  if ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) ||
-      nodes_added > kUnlimitedMaxInlinedSize) {
+  return nodes_added;
+}
+
+
+bool HGraphBuilder::TryInline(CallKind call_kind,
+                              Handle<JSFunction> target,
+                              ZoneList<Expression*>* arguments,
+                              HValue* receiver,
+                              int ast_id,
+                              int return_id,
+                              ReturnHandlingFlag return_handling) {
+  int nodes_added = InliningAstSize(target);
+  if (nodes_added == kNotInlinable) return false;
+
+  Handle<JSFunction> caller = info()->closure();
+
+  if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
     TraceInline(target, caller, "target AST is too large [early]");
     return false;
   }
 
+  Handle<SharedFunctionInfo> target_shared(target->shared());
+
 #if !defined(V8_TARGET_ARCH_IA32)
   // Target must be able to use caller's context.
   CompilationInfo* outer_info = info();
@@ -5249,8 +5908,8 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
   }
 
   // We don't want to add more than a certain number of nodes from inlining.
-  if ((FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) ||
-      inlined_count_ > kUnlimitedMaxInlinedNodes) {
+  if (inlined_count_ > Min(FLAG_max_inlined_nodes_cumulative,
+                           kUnlimitedMaxInlinedNodesCumulative)) {
     TraceInline(target, caller, "cumulative AST node limit reached");
     return false;
   }
@@ -5277,8 +5936,7 @@ 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 ((FLAG_limit_inlining && nodes_added > kMaxInlinedSize) ||
-      nodes_added > kUnlimitedMaxInlinedSize) {
+  if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
     TraceInline(target, caller, "target AST is too large [late]");
     return false;
   }
@@ -5373,19 +6031,42 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
   AddInstruction(context);
   inner_env->BindContext(context);
 #endif
+
   AddSimulate(return_id);
   current_block()->UpdateEnvironment(inner_env);
-  AddInstruction(new(zone()) HEnterInlined(target,
-                                           arguments->length(),
-                                           function,
-                                           call_kind,
-                                           function_state()->is_construct()));
+
+  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);
+
   // If the function uses arguments object create and bind one.
   if (function->scope()->arguments() != NULL) {
     ASSERT(function->scope()->arguments()->IsStackAllocated());
-    environment()->Bind(function->scope()->arguments(),
-                        graph()->GetArgumentsObject());
+    inner_env->Bind(function->scope()->arguments(),
+                    graph()->GetArgumentsObject());
   }
+
+
   VisitDeclarations(target_info.scope()->declarations());
   VisitStatements(function->body());
   if (HasStackOverflow()) {
@@ -5414,17 +6095,17 @@ bool HGraphBuilder::TryInline(CallKind call_kind,
           : undefined;
       current_block()->AddLeaveInlined(return_value,
                                        function_return(),
-                                       function_state()->drop_extra());
+                                       function_state());
     } else if (call_context()->IsEffect()) {
       ASSERT(function_return() != NULL);
-      current_block()->Goto(function_return(), function_state()->drop_extra());
+      current_block()->Goto(function_return(), function_state());
     } 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()->drop_extra());
+      current_block()->Goto(target, function_state());
     }
   }
 
@@ -5442,12 +6123,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()->drop_extra());
+      if_true->Goto(true_target, function_state());
     }
     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()->drop_extra());
+      if_false->Goto(false_target, function_state());
     }
     set_current_block(NULL);
     return true;
@@ -5683,7 +6364,27 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
         set_current_block(return_left);
         Push(left);
         set_current_block(return_right);
-        Push(right);
+        // The branch above always returns the right operand if either of
+        // them is NaN, but the spec requires that max/min(NaN, X) = NaN.
+        // We add another branch that checks if the left operand is NaN or not.
+        if (left_operand->representation().IsDouble()) {
+          // If left_operand != left_operand then it is NaN.
+          HCompareIDAndBranch* compare_nan = new(zone()) HCompareIDAndBranch(
+              left_operand, left_operand, Token::EQ);
+          compare_nan->SetInputRepresentation(left_operand->representation());
+          HBasicBlock* left_is_number = graph()->CreateBasicBlock();
+          HBasicBlock* left_is_nan = graph()->CreateBasicBlock();
+          compare_nan->SetSuccessorAt(0, left_is_number);
+          compare_nan->SetSuccessorAt(1, left_is_nan);
+          current_block()->Finish(compare_nan);
+          set_current_block(left_is_nan);
+          Push(left);
+          set_current_block(left_is_number);
+          Push(right);
+          return_right = CreateJoin(left_is_number, left_is_nan, expr->id());
+        } else {
+          Push(right);
+        }
 
         HBasicBlock* join = CreateJoin(return_left, return_right, expr->id());
         set_current_block(join);
@@ -5736,7 +6437,8 @@ bool HGraphBuilder::TryCallApply(Call* expr) {
   HValue* receiver = Pop();
 
   if (function_state()->outer() == NULL) {
-    HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
+    HInstruction* elements = AddInstruction(
+        new(zone()) HArgumentsElements(false));
     HInstruction* length =
         AddInstruction(new(zone()) HArgumentsLength(elements));
     HValue* wrapped_receiver =
@@ -5955,9 +6657,11 @@ void HGraphBuilder::VisitCall(Call* expr) {
       if (TryInlineCall(expr, true)) {   // Drop function from environment.
         return;
       } else {
-        call = PreProcessCall(new(zone()) HInvokeFunction(context,
-                                                          function,
-                                                          argument_count));
+        call = PreProcessCall(
+            new(zone()) HInvokeFunction(context,
+                                        function,
+                                        expr->target(),
+                                        argument_count));
         Drop(1);  // The function.
       }
 
@@ -5985,7 +6689,8 @@ 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_type() == JS_OBJECT_TYPE &&
+      constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize;
 }
 
 
@@ -6877,11 +7582,9 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
         Handle<Map> map = oracle()->GetCompareMap(expr);
         if (!map.is_null()) {
           AddInstruction(new(zone()) HCheckNonSmi(left));
-          AddInstruction(new(zone()) HCheckMap(left, map, NULL,
-                                               ALLOW_ELEMENT_TRANSITION_MAPS));
+          AddInstruction(HCheckMaps::NewWithTransitions(left, map));
           AddInstruction(new(zone()) HCheckNonSmi(right));
-          AddInstruction(new(zone()) HCheckMap(right, map, NULL,
-                                               ALLOW_ELEMENT_TRANSITION_MAPS));
+          AddInstruction(HCheckMaps::NewWithTransitions(right, map));
           HCompareObjectEqAndBranch* result =
               new(zone()) HCompareObjectEqAndBranch(left, right);
           result->set_position(expr->position());
@@ -6953,90 +7656,50 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
 
 
 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
-  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) {
+  ASSERT(globals_.is_empty());
+  AstVisitor::VisitDeclarations(declarations);
+  if (!globals_.is_empty()) {
     Handle<FixedArray> array =
-        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);
-        }
-      }
-    }
+       isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
+    for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
     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::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()) {
+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()) {
     case Variable::UNALLOCATED:
-      ++(*global_count);
+      globals_.Add(variable->name());
+      globals_.Add(variable->binding_needs_init()
+                       ? isolate()->factory()->the_hole_value()
+                       : isolate()->factory()->undefined_value());
       return;
     case Variable::PARAMETER:
     case Variable::LOCAL:
+      if (hole_init) {
+        HValue* value = graph()->GetConstantHole();
+        environment()->Bind(variable, value);
+      }
+      break;
     case Variable::CONTEXT:
-      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);
-        }
+      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());
       }
       break;
     case Variable::LOOKUP:
@@ -7045,48 +7708,74 @@ void HGraphBuilder::HandleDeclaration(VariableProxy* proxy,
 }
 
 
-void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
-  UNREACHABLE();
-}
-
-
-void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
-  UNREACHABLE();
+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::VisitModuleDeclaration(ModuleDeclaration* decl) {
+void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   UNREACHABLE();
 }
 
 
-void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) {
+void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) {
   UNREACHABLE();
 }
 
 
-void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) {
+void HGraphBuilder::VisitExportDeclaration(ExportDeclaration* declaration) {
   UNREACHABLE();
 }
 
 
 void HGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) {
-  // TODO(rossberg)
+  UNREACHABLE();
 }
 
 
 void HGraphBuilder::VisitModuleVariable(ModuleVariable* module) {
-  // TODO(rossberg)
+  UNREACHABLE();
 }
 
 
 void HGraphBuilder::VisitModulePath(ModulePath* module) {
-  // TODO(rossberg)
+  UNREACHABLE();
 }
 
 
 void HGraphBuilder::VisitModuleUrl(ModuleUrl* module) {
-  // TODO(rossberg)
+  UNREACHABLE();
 }
 
 
@@ -7207,7 +7896,8 @@ 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);
+  HInstruction* elements = AddInstruction(
+      new(zone()) HArgumentsElements(false));
   HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
   return ast_context()->ReturnInstruction(result, call->id());
 }
@@ -7221,7 +7911,8 @@ 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);
+  HInstruction* elements = AddInstruction(
+      new(zone()) HArgumentsElements(false));
   HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
   HAccessArgumentsAt* result =
       new(zone()) HAccessArgumentsAt(elements, length, index);
index e2779bb..909d07b 100644 (file)
@@ -42,6 +42,7 @@ namespace internal {
 
 // Forward declarations.
 class BitVector;
+class FunctionState;
 class HEnvironment;
 class HGraph;
 class HLoopInformation;
@@ -121,7 +122,7 @@ class HBasicBlock: public ZoneObject {
 
   void Finish(HControlInstruction* last);
   void FinishExit(HControlInstruction* instruction);
-  void Goto(HBasicBlock* block, bool drop_extra = false);
+  void Goto(HBasicBlock* block, FunctionState* state = NULL);
 
   int PredecessorIndexOf(HBasicBlock* predecessor) const;
   void AddSimulate(int ast_id) { AddInstruction(CreateSimulate(ast_id)); }
@@ -136,7 +137,7 @@ class HBasicBlock: public ZoneObject {
   // instruction and updating the bailout environment.
   void AddLeaveInlined(HValue* return_value,
                        HBasicBlock* target,
-                       bool drop_extra = false);
+                       FunctionState* state = NULL);
 
   // If a target block is tagged as an inline function return, all
   // predecessors should contain the inlined exit sequence:
@@ -240,7 +241,7 @@ class HLoopInformation: public ZoneObject {
   HStackCheck* stack_check_;
 };
 
-
+class BoundsCheckTable;
 class HGraph: public ZoneObject {
  public:
   explicit HGraph(CompilationInfo* info);
@@ -265,6 +266,7 @@ 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
@@ -357,6 +359,7 @@ 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_;
@@ -715,6 +718,16 @@ 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_;
 
@@ -741,6 +754,12 @@ 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_;
 };
 
@@ -851,15 +870,11 @@ 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 kUnlimitedMaxInlinedNodes = 1000;
-  static const int kUnlimitedMaxInlinedSize = 1000;
-  static const int kUnlimitedMaxSourceSize = 600;
+  static const int kUnlimitedMaxInlinedSourceSize = 100000;
+  static const int kUnlimitedMaxInlinedNodes = 10000;
+  static const int kUnlimitedMaxInlinedNodesCumulative = 10000;
 
   // Simple accessors.
   void set_function_state(FunctionState* state) { function_state_ = state; }
@@ -896,11 +911,6 @@ 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);
@@ -994,11 +1004,13 @@ class HGraphBuilder: public AstVisitor {
                                             LookupResult* lookup,
                                             bool is_store);
 
+  void EnsureArgumentsArePushedForAccess();
   bool TryArgumentsAccess(Property* expr);
 
   // Try to optimize fun.apply(receiver, arguments) pattern.
   bool TryCallApply(Call* expr);
 
+  int InliningAstSize(Handle<JSFunction> target);
   bool TryInline(CallKind call_kind,
                  Handle<JSFunction> target,
                  ZoneList<Expression*>* arguments,
@@ -1029,6 +1041,10 @@ 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,
@@ -1145,6 +1161,7 @@ class HGraphBuilder: public AstVisitor {
   HBasicBlock* current_block_;
 
   int inlined_count_;
+  ZoneList<Handle<Object> > globals_;
 
   Zone* zone_;
 
@@ -1219,6 +1236,30 @@ 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);
index 929b485..4ead80b 100644 (file)
@@ -640,6 +640,9 @@ class Assembler : public AssemblerBase {
   static const byte kJccShortPrefix = 0x70;
   static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
   static const byte kJcShortOpcode = kJccShortPrefix | carry;
+  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
+  static const byte kJzShortOpcode = kJccShortPrefix | zero;
+
 
   // ---------------------------------------------------------------------------
   // Code generation
index a5d42cf..a36763d 100644 (file)
@@ -831,7 +831,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
 
     // Copy all arguments from the array to the stack.
     Label entry, loop;
-    __ mov(eax, Operand(ebp, kIndexOffset));
+    __ mov(ecx, Operand(ebp, kIndexOffset));
     __ jmp(&entry);
     __ bind(&loop);
     __ mov(edx, Operand(ebp, kArgumentsOffset));  // load arguments
@@ -848,16 +848,17 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
     __ push(eax);
 
     // Update the index on the stack and in register eax.
-    __ mov(eax, Operand(ebp, kIndexOffset));
-    __ add(eax, Immediate(1 << kSmiTagSize));
-    __ mov(Operand(ebp, kIndexOffset), eax);
+    __ mov(ecx, Operand(ebp, kIndexOffset));
+    __ add(ecx, Immediate(1 << kSmiTagSize));
+    __ mov(Operand(ebp, kIndexOffset), ecx);
 
     __ bind(&entry);
-    __ cmp(eax, Operand(ebp, kLimitOffset));
+    __ cmp(ecx, 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));
index 4faa6a4..a1c6edd 100644 (file)
@@ -1681,6 +1681,11 @@ 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);
@@ -1690,31 +1695,37 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
     case Token::ADD:
     case Token::SUB:
     case Token::MUL:
-    case Token::DIV: {
+    case Token::DIV:
+    case Token::MOD: {
       Label not_floats;
       Label not_int32;
       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatures::Scope use_sse2(SSE2);
         FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
         FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
-        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, &not_int32);
-          __ j(carry, &not_int32);
+        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, &not_int32);
+            __ j(carry, &not_int32);
+          }
+          GenerateHeapResultAllocation(masm, &call_runtime);
+          __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
+          __ ret(0);
         }
-        GenerateHeapResultAllocation(masm, &call_runtime);
-        __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
-        __ ret(0);
       } else {  // SSE2 not available, use FPU.
         FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx);
         FloatingPointHelper::LoadFloatOperands(
@@ -1722,20 +1733,28 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
             ecx,
             FloatingPointHelper::ARGS_IN_REGISTERS);
         FloatingPointHelper::CheckFloatOperandsAreInt32(masm, &not_int32);
-        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();
+        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);
         }
-        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(&not_floats);
@@ -1744,10 +1763,6 @@ 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:
@@ -1758,11 +1773,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
       Label not_floats;
       Label not_int32;
       Label non_smi_result;
-      /*  {
-        CpuFeatures::Scope use_sse2(SSE2);
-        FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
-        FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
-        }*/
       FloatingPointHelper::LoadUnknownsAsIntegers(masm,
                                                   use_sse3_,
                                                   &not_floats);
@@ -1833,8 +1843,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
     default: UNREACHABLE(); break;
   }
 
-  // If an allocation fails, or SHR or MOD hit a hard case,
-  // use the runtime system to get the correct result.
+  // If an allocation fails, or SHR hits a hard case, use the runtime system to
+  // get the correct result.
   __ bind(&call_runtime);
 
   switch (op_) {
@@ -1855,8 +1865,6 @@ 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);
@@ -1957,7 +1965,7 @@ void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
         __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
         __ ret(0);
         __ bind(&after_alloc_failure);
-        __ ffree();
+        __ fstp(0);  // Pop FPU stack before calling runtime.
         __ jmp(&call_runtime);
       }
 
@@ -2161,8 +2169,8 @@ void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
         __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
         __ ret(0);
         __ bind(&after_alloc_failure);
-          __ ffree();
-          __ jmp(&call_runtime);
+        __ fstp(0);  // Pop FPU stack before calling runtime.
+        __ jmp(&call_runtime);
       }
         __ bind(&not_floats);
         break;
@@ -5006,11 +5014,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   __ j(not_equal, &not_outermost_js, Label::kNear);
   __ mov(Operand::StaticVariable(js_entry_sp), ebp);
   __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
-  Label cont;
-  __ jmp(&cont, Label::kNear);
+  __ jmp(&invoke, Label::kNear);
   __ bind(&not_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.
@@ -6162,7 +6168,11 @@ void SubStringStub::Generate(MacroAssembler* masm) {
   __ sub(ecx, edx);
   __ cmp(ecx, FieldOperand(eax, String::kLengthOffset));
   Label not_original_string;
-  __ j(not_equal, &not_original_string, Label::kNear);
+  // Shorter than original string's length: an actual substring.
+  __ j(below, &not_original_string, Label::kNear);
+  // Longer than original string's length or negative: unsafe arguments.
+  __ j(above, &runtime);
+  // Return original string.
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(3 * kPointerSize);
index ea61910..cff6454 100644 (file)
@@ -397,9 +397,25 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
   // Allocate new FixedDoubleArray.
   // edx: receiver
   // edi: length of source FixedArray (smi-tagged)
-  __ lea(esi, Operand(edi, times_4, FixedDoubleArray::kHeaderSize));
+  __ lea(esi, Operand(edi,
+                      times_4,
+                      FixedDoubleArray::kHeaderSize + kPointerSize));
   __ 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
index d13fa75..901e38b 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -91,9 +91,11 @@ void BreakLocationIterator::ClearDebugBreakAtSlot() {
   rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
 }
 
+// All debug break stubs support padding for LiveEdit.
+const bool Debug::FramePaddingLayout::kIsSupported = true;
 
-#define __ ACCESS_MASM(masm)
 
+#define __ ACCESS_MASM(masm)
 
 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
                                           RegList object_regs,
@@ -103,6 +105,13 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
+    // Load padding words on stack.
+    for (int i = 0; i < Debug::FramePaddingLayout::kInitialSize; i++) {
+      __ push(Immediate(Smi::FromInt(
+          Debug::FramePaddingLayout::kPaddingValue)));
+    }
+    __ push(Immediate(Smi::FromInt(Debug::FramePaddingLayout::kInitialSize)));
+
     // Store the registers containing live values on the expression stack to
     // make sure that these are correctly updated during GC. Non object values
     // are stored as a smi causing it to be untouched by GC.
@@ -134,6 +143,10 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
     CEntryStub ceb(1);
     __ CallStub(&ceb);
 
+    // Automatically find register that could be used after register restore.
+    // We need one register for padding skip instructions.
+    Register unused_reg = { -1 };
+
     // Restore the register values containing object pointers from the
     // expression stack.
     for (int i = kNumJSCallerSaved; --i >= 0;) {
@@ -142,15 +155,29 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
       if (FLAG_debug_code) {
         __ Set(reg, Immediate(kDebugZapValue));
       }
+      bool taken = reg.code() == esi.code();
       if ((object_regs & (1 << r)) != 0) {
         __ pop(reg);
+        taken = true;
       }
       if ((non_object_regs & (1 << r)) != 0) {
         __ pop(reg);
         __ SmiUntag(reg);
+        taken = true;
+      }
+      if (!taken) {
+        unused_reg = reg;
       }
     }
 
+    ASSERT(unused_reg.code() != -1);
+
+    // Read current padding counter and skip corresponding number of words.
+    __ pop(unused_reg);
+    // We divide stored value by 2 (untagging) and multiply it by word's size.
+    STATIC_ASSERT(kSmiTagSize == 1);
+    __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0));
+
     // Get rid of the internal frame.
   }
 
@@ -172,10 +199,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, eax.bit() | ecx.bit(), 0, false);
+  Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
 }
 
 
@@ -194,10 +221,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, eax.bit() | edx.bit(), 0, false);
+  Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
 }
 
 
index 92d7cc1..73961e1 100644 (file)
@@ -239,13 +239,13 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code,
   // ok:
 
   if (FLAG_count_based_interrupts) {
-    ASSERT_EQ(*(call_target_address - 3), kJnsInstruction);
-    ASSERT_EQ(*(call_target_address - 2), kJnsOffset);
+    ASSERT_EQ(kJnsInstruction, *(call_target_address - 3));
+    ASSERT_EQ(kJnsOffset,      *(call_target_address - 2));
   } else {
-    ASSERT_EQ(*(call_target_address - 3), kJaeInstruction);
-    ASSERT_EQ(*(call_target_address - 2), kJaeOffset);
+    ASSERT_EQ(kJaeInstruction, *(call_target_address - 3));
+    ASSERT_EQ(kJaeOffset,      *(call_target_address - 2));
   }
-  ASSERT_EQ(*(call_target_address - 1), kCallInstruction);
+  ASSERT_EQ(kCallInstruction,  *(call_target_address - 1));
   *(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(*(call_target_address - 3), kNopByteOne);
-  ASSERT_EQ(*(call_target_address - 2), kNopByteTwo);
-  ASSERT_EQ(*(call_target_address - 1), kCallInstruction);
+  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;
@@ -548,6 +548,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -555,7 +557,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 6 * kPointerSize;
+  unsigned fixed_frame_size = 7 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -620,6 +622,15 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -641,8 +652,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
index 62a2c2a..10fe77b 100644 (file)
@@ -101,13 +101,6 @@ 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
@@ -269,11 +262,11 @@ void FullCodeGenerator::Generate() {
       // For named function expressions, declare the function name as a
       // constant.
       if (scope()->is_function_scope() && scope()->function() != NULL) {
-        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);
+        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);
       }
       VisitDeclarations(scope()->declarations());
     }
@@ -763,60 +756,51 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
 }
 
 
-void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
-                                        VariableMode mode,
-                                        FunctionLiteral* function) {
+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) {
   // 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 binding_needs_init = (function == NULL) &&
-      (mode == CONST || mode == CONST_HARMONY || mode == LET);
+  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_->Add(variable->name());
+      globals_->Add(variable->binding_needs_init()
+                        ? isolate()->factory()->the_hole_value()
+                        : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
     case Variable::LOCAL:
-      if (function != NULL) {
-        Comment cmnt(masm_, "[ Declaration");
-        VisitForAccumulatorValue(function);
-        __ mov(StackOperand(variable), result_register());
-      } else if (binding_needs_init) {
-        Comment cmnt(masm_, "[ Declaration");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
         __ mov(StackOperand(variable),
                Immediate(isolate()->factory()->the_hole_value()));
       }
       break;
 
     case Variable::CONTEXT:
-      // 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");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        EmitDebugCheckDeclarationContext(variable);
         __ mov(ContextOperand(esi, variable->index()),
                Immediate(isolate()->factory()->the_hole_value()));
         // No write barrier since the hole value is in old space.
@@ -825,14 +809,12 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       break;
 
     case Variable::LOOKUP: {
-      Comment cmnt(masm_, "[ Declaration");
+      Comment cmnt(masm_, "[ VariableDeclaration");
       __ push(esi);
       __ push(Immediate(variable->name()));
-      // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR ||
-             mode == CONST ||
-             mode == CONST_HARMONY ||
-             mode == LET);
+      // VariableDeclaration nodes are always introduced in one of four modes.
+      ASSERT(mode == VAR || mode == LET ||
+             mode == CONST || mode == CONST_HARMONY);
       PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
           ? READ_ONLY : NONE;
       __ push(Immediate(Smi::FromInt(attr)));
@@ -840,9 +822,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       // 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 (function != NULL) {
-        VisitForStackValue(function);
-      } else if (binding_needs_init) {
+      if (hole_init) {
         __ push(Immediate(isolate()->factory()->the_hole_value()));
       } else {
         __ push(Immediate(Smi::FromInt(0)));  // Indicates no initial value.
@@ -854,6 +834,118 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
 }
 
 
+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.
@@ -1194,7 +1286,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
 
   // All extension objects were empty and it is safe to use a global
   // load IC call.
-  __ mov(eax, GlobalObjectOperand());
+  __ mov(edx, GlobalObjectOperand());
   __ mov(ecx, var->name());
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1278,7 +1370,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(eax, GlobalObjectOperand());
+      __ mov(edx, GlobalObjectOperand());
       __ mov(ecx, var->name());
       Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
       CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
@@ -1672,9 +1764,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
       break;
     case NAMED_PROPERTY:
       if (expr->is_compound()) {
-        // We need the receiver both on the stack and in the accumulator.
-        VisitForAccumulatorValue(property->obj());
-        __ push(result_register());
+        // We need the receiver both on the stack and in edx.
+        VisitForStackValue(property->obj());
+        __ mov(edx, Operand(esp, 0));
       } else {
         VisitForStackValue(property->obj());
       }
@@ -1682,9 +1774,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
-        VisitForAccumulatorValue(property->key());
-        __ mov(edx, Operand(esp, 0));
-        __ push(eax);
+        VisitForStackValue(property->key());
+        __ mov(edx, Operand(esp, kPointerSize));  // Object.
+        __ mov(ecx, Operand(esp, 0));             // Key.
       } else {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
@@ -1927,7 +2019,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
       VisitForStackValue(prop->obj());
       VisitForAccumulatorValue(prop->key());
       __ mov(ecx, eax);
-      __ pop(edx);
+      __ pop(edx);  // Receiver.
       __ pop(eax);  // Restore value.
       Handle<Code> ic = is_classic_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
@@ -2033,6 +2125,9 @@ 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);
@@ -2075,6 +2170,9 @@ 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
@@ -2087,7 +2185,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
     __ pop(result_register());
   }
 
-  __ pop(ecx);
+  __ pop(ecx);  // Key.
   if (expr->ends_initialization_block()) {
     __ mov(edx, Operand(esp, 0));  // Leave receiver on the stack for later.
   } else {
@@ -2120,12 +2218,14 @@ 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);
+    __ pop(edx);                     // Object.
+    __ mov(ecx, result_register());  // Key.
     EmitKeyedPropertyLoad(expr);
     context()->Plug(eax);
   }
@@ -4017,15 +4117,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
       __ push(Immediate(Smi::FromInt(0)));
     }
     if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the accumulator.
+      // Put the object both on the stack and in edx.
       VisitForAccumulatorValue(prop->obj());
       __ push(eax);
+      __ mov(edx, eax);
       EmitNamedPropertyLoad(prop);
     } else {
       VisitForStackValue(prop->obj());
-      VisitForAccumulatorValue(prop->key());
-      __ mov(edx, Operand(esp, 0));
-      __ push(eax);
+      VisitForStackValue(prop->key());
+      __ mov(edx, Operand(esp, kPointerSize));  // Object.
+      __ mov(ecx, Operand(esp, 0));             // Key.
       EmitKeyedPropertyLoad(prop);
     }
   }
@@ -4172,7 +4273,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
 
   if (proxy != NULL && proxy->var()->IsUnallocated()) {
     Comment cmnt(masm_, "Global variable");
-    __ mov(eax, GlobalObjectOperand());
+    __ mov(edx, 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
@@ -4437,7 +4538,8 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope()) {
+  if (declaration_scope->is_global_scope() ||
+      declaration_scope->is_module_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
index 33f247a..dc64a09 100644 (file)
@@ -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, eax, edx, &miss);
+  StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &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, eax, edx, ebx, &miss,
+  StubCompiler::GenerateLoadStringLength(masm, edx, eax, 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, eax, edx, ebx, &miss);
+  StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
   __ bind(&miss);
   StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
 }
@@ -383,7 +383,7 @@ static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
   __ j(below, slow_case);
 
   // Check that the key is a positive smi.
-  __ test(key, Immediate(0x8000001));
+  __ test(key, Immediate(0x80000001));
   __ j(not_zero, slow_case);
 
   // Load the elements into scratch1 and check its map.
@@ -396,7 +396,7 @@ static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
   __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset));
   __ sub(scratch2, Immediate(Smi::FromInt(2)));
   __ cmp(key, scratch2);
-  __ j(greater_equal, unmapped_case);
+  __ j(above_equal, unmapped_case);
 
   // Load element index and check whether it is the hole.
   const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize;
@@ -443,7 +443,7 @@ static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
 
 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -451,39 +451,34 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   Label probe_dictionary, check_number_dictionary;
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(eax, &check_string);
+  __ JumpIfNotSmi(ecx, &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, ecx, Map::kHasIndexedInterceptor, &slow);
+      masm, edx, eax, Map::kHasIndexedInterceptor, &slow);
 
   // Check the receiver's map to see if it has fast elements.
-  __ CheckFastElements(ecx, &check_number_dictionary);
-
-  GenerateFastArrayLoad(masm,
-                        edx,
-                        eax,
-                        ecx,
-                        eax,
-                        NULL,
-                        &slow);
+  __ CheckFastElements(eax, &check_number_dictionary);
+
+  GenerateFastArrayLoad(masm, edx, ecx, eax, 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, eax);
+  __ mov(ebx, ecx);
   __ SmiUntag(ebx);
-  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
+  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
 
   // Check whether the elements is a number dictionary.
   // edx: receiver
   // ebx: untagged index
-  // eax: key
-  // ecx: elements
-  __ CheckMap(ecx,
+  // ecx: key
+  // eax: elements
+  __ CheckMap(eax,
               isolate->factory()->hash_table_map(),
               &slow,
               DONT_DO_SMI_CHECK);
@@ -491,13 +486,7 @@ 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,
-                              ecx,
-                              eax,
-                              ebx,
-                              edx,
-                              edi,
-                              eax);
+  __ LoadFromNumberDictionary(&slow_pop_receiver, eax, ecx, ebx, edx, edi, eax);
   // Pop receiver before returning.
   __ pop(edx);
   __ ret(0);
@@ -509,15 +498,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   __ bind(&slow);
   // Slow case: jump to runtime.
   // edx: receiver
-  // eax: key
+  // ecx: key
   __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_string);
-  GenerateKeyStringCheck(masm, eax, ecx, ebx, &index_string, &slow);
+  GenerateKeyStringCheck(masm, ecx, eax, ebx, &index_string, &slow);
 
   GenerateKeyedLoadReceiverCheck(
-      masm, edx, ecx, Map::kHasNamedInterceptor, &slow);
+      masm, edx, eax, Map::kHasNamedInterceptor, &slow);
 
   // If the receiver is a fast-case object, check the keyed lookup
   // cache. Otherwise probe the dictionary.
@@ -526,15 +515,18 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
          Immediate(isolate->factory()->hash_table_map()));
   __ j(equal, &probe_dictionary);
 
-  // Load the map of the receiver, compute the keyed lookup cache hash
+  // The receiver's map is still in eax, compute the keyed lookup cache hash
   // based on 32 bits of the map pointer and the string hash.
-  __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
-  __ mov(ecx, ebx);
-  __ shr(ecx, KeyedLookupCache::kMapHashShift);
-  __ mov(edi, FieldOperand(eax, String::kHashFieldOffset));
+  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));
   __ shr(edi, String::kHashShift);
-  __ xor_(ecx, edi);
-  __ and_(ecx, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
+  __ xor_(eax, edi);
+  __ and_(eax, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
@@ -546,7 +538,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
 
   for (int i = 0; i < kEntriesPerBucket - 1; i++) {
     Label try_next_entry;
-    __ mov(edi, ecx);
+    __ mov(edi, eax);
     __ shl(edi, kPointerSizeLog2 + 1);
     if (i != 0) {
       __ add(edi, Immediate(kPointerSize * i * 2));
@@ -554,25 +546,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(eax, Operand::StaticArray(edi, times_1, cache_keys));
+    __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys));
     __ j(equal, &hit_on_nth_entry[i]);
     __ bind(&try_next_entry);
   }
 
-  __ lea(edi, Operand(ecx, 1));
+  __ lea(edi, Operand(eax, 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(eax, Operand::StaticArray(edi, times_1, cache_keys));
+  __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys));
   __ j(not_equal, &slow);
 
   // Get field offset.
   // edx     : receiver
   // ebx     : receiver's map
-  // eax     : key
-  // ecx     : lookup cache index
+  // ecx     : key
+  // eax     : lookup cache index
   ExternalReference cache_field_offsets =
       ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
 
@@ -580,12 +572,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
     __ bind(&hit_on_nth_entry[i]);
     if (i != 0) {
-      __ add(ecx, Immediate(i));
+      __ add(eax, Immediate(i));
     }
     __ mov(edi,
-           Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
-    __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
-    __ sub(edi, ecx);
+           Operand::StaticArray(eax, times_pointer_size, cache_field_offsets));
+    __ movzx_b(eax, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
+    __ sub(edi, eax);
     __ j(above_equal, &property_array_property);
     if (i != 0) {
       __ jmp(&load_in_object_property);
@@ -594,9 +586,9 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
 
   // Load in-object property.
   __ bind(&load_in_object_property);
-  __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
-  __ add(ecx, edi);
-  __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
+  __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceSizeOffset));
+  __ add(eax, edi);
+  __ mov(eax, FieldOperand(edx, eax, times_pointer_size, 0));
   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
@@ -612,16 +604,16 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   // exists.
   __ bind(&probe_dictionary);
 
-  __ mov(ecx, FieldOperand(edx, JSObject::kMapOffset));
-  __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
-  GenerateGlobalInstanceTypeCheck(masm, ecx, &slow);
+  __ mov(eax, FieldOperand(edx, JSObject::kMapOffset));
+  __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
+  GenerateGlobalInstanceTypeCheck(masm, eax, &slow);
 
-  GenerateDictionaryLoad(masm, &slow, ebx, eax, ecx, edi, eax);
+  GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax);
   __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
   __ ret(0);
 
   __ bind(&index_string);
-  __ IndexFromHash(ebx, eax);
+  __ IndexFromHash(ebx, ecx);
   // Now jump to the place where smi keys are handled.
   __ jmp(&index_smi);
 }
@@ -629,15 +621,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
 
 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key (index)
+  //  -- ecx    : key (index)
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
   Label miss;
 
   Register receiver = edx;
-  Register index = eax;
-  Register scratch = ecx;
+  Register index = ecx;
+  Register scratch = ebx;
   Register result = eax;
 
   StringCharAtGenerator char_at_generator(receiver,
@@ -661,7 +653,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
 
 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -671,24 +663,24 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
   __ JumpIfSmi(edx, &slow);
 
   // Check that the key is an array index, that is Uint32.
-  __ test(eax, Immediate(kSmiTagMask | kSmiSignMask));
+  __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask));
   __ j(not_zero, &slow);
 
   // Get the map of the receiver.
-  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
+  __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset));
 
   // Check that it has indexed interceptor and access checks
   // are not enabled for this object.
-  __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset));
-  __ and_(ecx, Immediate(kSlowCaseBitFieldMask));
-  __ cmp(ecx, Immediate(1 << Map::kHasIndexedInterceptor));
+  __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset));
+  __ and_(eax, Immediate(kSlowCaseBitFieldMask));
+  __ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor));
   __ j(not_zero, &slow);
 
   // Everything is fine, call runtime.
-  __ pop(ecx);
+  __ pop(eax);
   __ push(edx);  // receiver
-  __ push(eax);  // key
-  __ push(ecx);  // return address
+  __ push(ecx);  // key
+  __ push(eax);  // return address
 
   // Perform tail call to the entry.
   ExternalReference ref =
@@ -703,20 +695,20 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
 
 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
   Label slow, notin;
   Factory* factory = masm->isolate()->factory();
   Operand mapped_location =
-      GenerateMappedArgumentsLookup(masm, edx, eax, ebx, ecx, &notin, &slow);
+      GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, &notin, &slow);
   __ mov(eax, mapped_location);
   __ Ret();
   __ bind(&notin);
   // The unmapped lookup expects that the parameter map is in ebx.
   Operand unmapped_location =
-      GenerateUnmappedArgumentsLookup(masm, eax, ebx, ecx, &slow);
+      GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow);
   __ cmp(unmapped_location, factory->the_hole_value());
   __ j(equal, &slow);
   __ mov(eax, unmapped_location);
@@ -1308,15 +1300,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, eax, ecx, ebx,
-                                                  edx);
+  Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx,
+                                                  eax);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -1325,17 +1317,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, eax, edx, ebx, &miss);
+  GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
 
-  // edx: elements
+  // eax: elements
   // Search the dictionary placing the result in eax.
-  GenerateDictionaryLoad(masm, &miss, edx, ecx, edi, ebx, eax);
+  GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, eax);
   __ ret(0);
 
   // Cache miss: Jump to runtime.
@@ -1346,15 +1338,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(eax);  // receiver
+  __ push(edx);  // receiver
   __ push(ecx);  // name
   __ push(ebx);  // return address
 
@@ -1367,7 +1359,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
 
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -1376,7 +1368,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
 
   __ pop(ebx);
   __ push(edx);  // receiver
-  __ push(eax);  // name
+  __ push(ecx);  // name
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
@@ -1390,14 +1382,14 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, bool force_generic) {
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
 
   __ pop(ebx);
   __ push(edx);  // receiver
-  __ push(eax);  // name
+  __ push(ecx);  // name
   __ push(ebx);  // return address
 
   // Perform tail call to the entry.
@@ -1735,12 +1727,12 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
 
   // Activate inlined smi code.
   if (previous_state == UNINITIALIZED) {
-    PatchInlinedSmiCode(address());
+    PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
   }
 }
 
 
-void PatchInlinedSmiCode(Address address) {
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
   // The address of the instruction following the call.
   Address test_instruction_address =
       address + Assembler::kCallTargetAddressOffset;
@@ -1761,14 +1753,18 @@ void PatchInlinedSmiCode(Address address) {
            address, test_instruction_address, delta);
   }
 
-  // Patch with a short conditional jump. There must be a
-  // short jump-if-carry/not-carry at this position.
+  // Patch with a short conditional jump. Enabling means switching from a short
+  // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the
+  // reverse operation of that.
   Address jmp_address = test_instruction_address - delta;
-  ASSERT(*jmp_address == Assembler::kJncShortOpcode ||
-         *jmp_address == Assembler::kJcShortOpcode);
-  Condition cc = *jmp_address == Assembler::kJncShortOpcode
-      ? not_zero
-      : zero;
+  ASSERT((check == ENABLE_INLINED_SMI_CHECK)
+         ? (*jmp_address == Assembler::kJncShortOpcode ||
+            *jmp_address == Assembler::kJcShortOpcode)
+         : (*jmp_address == Assembler::kJnzShortOpcode ||
+            *jmp_address == Assembler::kJzShortOpcode));
+  Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
+      ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
+      : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
 }
 
index 8fb4c79..455c502 100644 (file)
@@ -2059,8 +2059,9 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                   RelocInfo::CODE_TARGET,
                   instr,
                   RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
-  ASSERT(instr->HasDeoptimizationEnvironment());
-  LEnvironment* env = instr->deoptimization_environment();
+  // Get the deoptimization index of the LLazyBailout-environment that
+  // corresponds to this instruction.
+  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
   safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
 
   // Put the result value into the eax slot and restore all registers.
@@ -2114,7 +2115,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
 
 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
-  ASSERT(ToRegister(instr->global_object()).is(eax));
+  ASSERT(ToRegister(instr->global_object()).is(edx));
   ASSERT(ToRegister(instr->result()).is(eax));
 
   __ mov(ecx, instr->name());
@@ -2273,46 +2274,41 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
   Register result = ToRegister(instr->result());
 
   int map_count = instr->hydrogen()->types()->length();
+  bool need_generic = instr->hydrogen()->need_generic();
+
+  if (map_count == 0 && !need_generic) {
+    DeoptimizeIf(no_condition, instr->environment());
+    return;
+  }
   Handle<String> name = instr->hydrogen()->name();
-  if (map_count == 0) {
-    ASSERT(instr->hydrogen()->need_generic());
-    __ mov(ecx, name);
-    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  } else {
-    Label done;
-    for (int i = 0; i < map_count - 1; ++i) {
-      Handle<Map> map = instr->hydrogen()->types()->at(i);
+  Label done;
+  for (int i = 0; i < map_count; ++i) {
+    bool last = (i == map_count - 1);
+    Handle<Map> map = instr->hydrogen()->types()->at(i);
+    __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+    if (last && !need_generic) {
+      DeoptimizeIf(not_equal, instr->environment());
+      EmitLoadFieldOrConstantFunction(result, object, map, name);
+    } else {
       Label next;
-      __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
       __ j(not_equal, &next, Label::kNear);
       EmitLoadFieldOrConstantFunction(result, object, map, name);
       __ jmp(&done, Label::kNear);
       __ bind(&next);
     }
-    Handle<Map> map = instr->hydrogen()->types()->last();
-    __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
-    if (instr->hydrogen()->need_generic()) {
-      Label generic;
-      __ j(not_equal, &generic, Label::kNear);
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-      __ jmp(&done, Label::kNear);
-      __ bind(&generic);
-      __ mov(ecx, name);
-      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      CallCode(ic, RelocInfo::CODE_TARGET, instr);
-    } else {
-      DeoptimizeIf(not_equal, instr->environment());
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-    }
-    __ bind(&done);
   }
+  if (need_generic) {
+    __ mov(ecx, name);
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  }
+  __ bind(&done);
 }
 
 
 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
-  ASSERT(ToRegister(instr->object()).is(eax));
+  ASSERT(ToRegister(instr->object()).is(edx));
   ASSERT(ToRegister(instr->result()).is(eax));
 
   __ mov(ecx, instr->name());
@@ -2533,7 +2529,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(eax));
+  ASSERT(ToRegister(instr->key()).is(ecx));
 
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -2543,25 +2539,29 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
   Register result = ToRegister(instr->result());
 
-  // 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);
+  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);
 
-  // Arguments adaptor frame present.
-  __ bind(&adapted);
-  __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
+    // 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);
+    // Result is the frame pointer for the frame if not adapted and for the real
+    // frame below the adaptor frame if adapted.
+    __ bind(&done);
+  }
 }
 
 
@@ -2666,7 +2666,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
 
   // Invoke the function.
   __ bind(&invoke);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -2683,6 +2683,11 @@ 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());
@@ -2729,7 +2734,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 EDIState edi_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;
 
@@ -2737,7 +2743,9 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
   RecordPosition(pointers->position());
 
   if (can_invoke_directly) {
-    __ LoadHeapObject(edi, function);
+    if (edi_state == EDI_UNINITIALIZED) {
+      __ LoadHeapObject(edi, function);
+    }
 
     // Change context if needed.
     bool change_context =
@@ -2780,7 +2788,8 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    EDI_UNINITIALIZED);
 }
 
 
@@ -2911,11 +2920,13 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
     __ cmp(output_reg, 0x80000000u);
     DeoptimizeIf(equal, instr->environment());
   } else {
+    Label negative_sign;
     Label done;
-    // Deoptimize on negative numbers.
+    // Deoptimize on unordered.
     __ xorps(xmm_scratch, xmm_scratch);  // Zero the register.
     __ ucomisd(input_reg, xmm_scratch);
-    DeoptimizeIf(below, instr->environment());
+    DeoptimizeIf(parity_even, instr->environment());
+    __ j(below, &negative_sign, Label::kNear);
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       // Check for negative zero.
@@ -2931,10 +2942,21 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
 
     // Use truncating instruction (OK because input is positive).
     __ cvttsd2si(output_reg, Operand(input_reg));
-
     // Overflow is signalled with minint.
     __ cmp(output_reg, 0x80000000u);
     DeoptimizeIf(equal, instr->environment());
+    __ jmp(&done, Label::kNear);
+
+    // Non-zero negative reaches here
+    __ bind(&negative_sign);
+    // Truncate, then compare and compensate
+    __ cvttsd2si(output_reg, Operand(input_reg));
+    __ cvtsi2sd(xmm_scratch, output_reg);
+    __ ucomisd(input_reg, xmm_scratch);
+    __ j(equal, &done, Label::kNear);
+    __ sub(output_reg, Immediate(1));
+    DeoptimizeIf(overflow, instr->environment());
+
     __ bind(&done);
   }
 }
@@ -3226,13 +3248,21 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
   ASSERT(ToRegister(instr->function()).is(edi));
   ASSERT(instr->HasPointerMap());
-  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);
+
+  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);
+  }
 }
 
 
@@ -3287,7 +3317,11 @@ 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);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    EDI_UNINITIALIZED);
 }
 
 
@@ -3460,15 +3494,18 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
 void LCodeGen::DoStoreKeyedFastDoubleElement(
     LStoreKeyedFastDoubleElement* instr) {
   XMMRegister value = ToDoubleRegister(instr->value());
-  Label have_value;
 
-  __ ucomisd(value, value);
-  __ j(parity_odd, &have_value);  // NaN.
+  if (instr->NeedsCanonicalization()) {
+    Label have_value;
 
-  ExternalReference canonical_nan_reference =
-      ExternalReference::address_of_canonical_non_hole_nan();
-  __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
-  __ bind(&have_value);
+    __ 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);
+  }
 
   Operand double_store_operand = BuildFastArrayOperand(
       instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
@@ -4181,12 +4218,21 @@ void LCodeGen::DoCheckMapCommon(Register reg,
 }
 
 
-void LCodeGen::DoCheckMap(LCheckMap* instr) {
+void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
   LOperand* input = instr->InputAt(0);
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  Handle<Map> map = instr->hydrogen()->map();
-  DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment());
+
+  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);
 }
 
 
@@ -4297,6 +4343,14 @@ 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);
@@ -4331,14 +4385,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
@@ -4346,8 +4400,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
   __ Set(result, Immediate(0));
 
   PushSafepointRegistersScope scope(this);
-  __ PushHeapObject(constructor);
-  CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr, instr->context());
+  __ push(Immediate(Smi::FromInt(instance_size)));
+  CallRuntimeFromDeferred(
+      Runtime::kAllocateInNewSpace, 1, instr, instr->context());
   __ StoreToSafepointRegisterSlot(result, eax);
 }
 
@@ -4415,6 +4470,13 @@ 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.
@@ -4484,9 +4546,10 @@ 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 = JSObject::GetElement(object, i);
+        Handle<Object> value(fast_elements->get(i));
         if (value->IsJSObject()) {
           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
           __ lea(ecx, Operand(result, *offset));
@@ -4510,6 +4573,23 @@ 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.
@@ -4794,7 +4874,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   LOperand* key = instr->key();
   __ push(ToOperand(obj));
   EmitPushTaggedOperand(key);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   // Create safepoint generator that will also ensure enough space in the
@@ -4892,7 +4972,7 @@ void LCodeGen::DoIn(LIn* instr) {
   LOperand* key = instr->key();
   EmitPushTaggedOperand(key);
   EmitPushTaggedOperand(obj);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
index 52befc6..a2810f0 100644 (file)
@@ -206,12 +206,18 @@ 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);
+                         CallKind call_kind,
+                         EDIState edi_state);
 
   void RecordSafepointWithLazyDeopt(LInstruction* instr,
                                     SafepointMode safepoint_mode);
index 2bfbb67..5adaf43 100644 (file)
@@ -729,22 +729,6 @@ 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) {
@@ -757,8 +741,10 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
   if (hinstr->HasObservableSideEffects()) {
     ASSERT(hinstr->next()->IsSimulate());
     HSimulate* sim = HSimulate::cast(hinstr->next());
-    instr = SetInstructionPendingDeoptimizationEnvironment(
-        instr, sim->ast_id());
+    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();
   }
 
   // If instruction does not have side-effects lazy deoptimization
@@ -776,12 +762,6 @@ 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_));
@@ -1330,6 +1310,7 @@ 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);
@@ -1354,6 +1335,12 @@ 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());
@@ -1800,9 +1787,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
+LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  LCheckMap* result = new(zone()) LCheckMap(value);
+  LCheckMaps* result = new(zone()) LCheckMaps(value);
   return AssignEnvironment(result);
 }
 
@@ -1862,7 +1849,7 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
 
 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* global_object = UseFixed(instr->global_object(), eax);
+  LOperand* global_object = UseFixed(instr->global_object(), edx);
   LLoadGlobalGeneric* result =
       new(zone()) LLoadGlobalGeneric(context, global_object);
   return MarkAsCall(DefineFixed(result, eax), instr);
@@ -1922,7 +1909,7 @@ LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
   ASSERT(instr->representation().IsTagged());
   if (instr->need_generic()) {
     LOperand* context = UseFixed(instr->context(), esi);
-    LOperand* obj = UseFixed(instr->object(), eax);
+    LOperand* obj = UseFixed(instr->object(), edx);
     LLoadNamedFieldPolymorphic* result =
         new(zone()) LLoadNamedFieldPolymorphic(context, obj);
     return MarkAsCall(DefineFixed(result, eax), instr);
@@ -1938,7 +1925,7 @@ LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
 
 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
-  LOperand* object = UseFixed(instr->object(), eax);
+  LOperand* object = UseFixed(instr->object(), edx);
   LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object);
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
@@ -2017,7 +2004,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(), eax);
+  LOperand* key = UseFixed(instr->key(), ecx);
 
   LLoadKeyedGeneric* result =
       new(zone()) LLoadKeyedGeneric(context, object, key);
@@ -2348,9 +2335,12 @@ 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_->
-        set_deoptimization_environment(result->environment());
-    ClearInstructionPendingDeoptimizationEnvironment();
+        SetDeferredLazyDeoptimizationEnvironment(result->environment());
+    instruction_pending_deoptimization_environment_ = NULL;
+    pending_deoptimization_ast_id_ = AstNode::kNoNumber;
     return result;
   }
 
@@ -2380,6 +2370,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
                                                undefined,
                                                instr->call_kind(),
                                                instr->is_construct());
+  if (instr->arguments_var() != NULL) {
+    inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
+  }
   current_block_->UpdateEnvironment(inner);
   chunk_->AddInlinedClosure(instr->closure());
   return NULL;
@@ -2387,10 +2380,20 @@ 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 NULL;
+  return pop;
 }
 
 
index 4ecce96..09f0b0d 100644 (file)
@@ -65,7 +65,7 @@ class LCodeGen;
   V(CallStub)                                   \
   V(CheckFunction)                              \
   V(CheckInstanceType)                          \
-  V(CheckMap                                  \
+  V(CheckMaps)                                  \
   V(CheckNonSmi)                                \
   V(CheckPrototypeMaps)                         \
   V(CheckSmi)                                   \
@@ -174,7 +174,8 @@ class LCodeGen;
   V(CheckMapValue)                              \
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
-  V(WrapReceiver)
+  V(WrapReceiver)                               \
+  V(Drop)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -198,8 +199,7 @@ class LInstruction: public ZoneObject {
   LInstruction()
       : environment_(NULL),
         hydrogen_value_(NULL),
-        is_call_(false),
-        is_save_doubles_(false) { }
+        is_call_(false) { }
   virtual ~LInstruction() { }
 
   virtual void CompileToNative(LCodeGen* generator) = 0;
@@ -242,22 +242,12 @@ class LInstruction: public ZoneObject {
   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
 
-  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;
@@ -278,9 +268,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_;
 };
 
 
@@ -525,9 +513,8 @@ 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)
 };
 
 
@@ -844,6 +831,15 @@ 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_;
 };
 
 
@@ -1401,6 +1397,19 @@ 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")
@@ -1489,6 +1498,7 @@ 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(); }
 };
 
 
@@ -1787,6 +1797,8 @@ 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(); }
 };
 
 
@@ -1949,14 +1961,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> {
 };
 
 
-class LCheckMap: public LTemplateInstruction<0, 1, 0> {
+class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckMap(LOperand* value) {
+  explicit LCheckMaps(LOperand* value) {
     inputs_[0] = value;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
-  DECLARE_HYDROGEN_ACCESSOR(CheckMap)
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
+  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
 };
 
 
@@ -2471,11 +2483,6 @@ 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);
index 60e38a6..c31b0c2 100644 (file)
@@ -2566,7 +2566,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
 CodePatcher::CodePatcher(byte* address, int size)
     : address_(address),
       size_(size),
-      masm_(Isolate::Current(), address, size + Assembler::kGap) {
+      masm_(NULL, address, size + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
index 04d6b62..0029f33 100644 (file)
@@ -501,9 +501,13 @@ void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c,
 void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c,
                                                       uint32_t mask,
                                                       Label* on_equal) {
-  __ mov(eax, current_character());
-  __ and_(eax, mask);
-  __ cmp(eax, c);
+  if (c == 0) {
+    __ test(current_character(), Immediate(mask));
+  } else {
+    __ mov(eax, mask);
+    __ and_(eax, current_character());
+    __ cmp(eax, c);
+  }
   BranchOrBacktrack(equal, on_equal);
 }
 
@@ -511,9 +515,13 @@ void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c,
 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c,
                                                          uint32_t mask,
                                                          Label* on_not_equal) {
-  __ mov(eax, current_character());
-  __ and_(eax, mask);
-  __ cmp(eax, c);
+  if (c == 0) {
+    __ test(current_character(), Immediate(mask));
+  } else {
+    __ mov(eax, mask);
+    __ and_(eax, current_character());
+    __ cmp(eax, c);
+  }
   BranchOrBacktrack(not_equal, on_not_equal);
 }
 
@@ -525,12 +533,51 @@ void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd(
     Label* on_not_equal) {
   ASSERT(minus < String::kMaxUtf16CodeUnit);
   __ lea(eax, Operand(current_character(), -minus));
-  __ and_(eax, mask);
-  __ cmp(eax, c);
+  if (c == 0) {
+    __ test(eax, Immediate(mask));
+  } else {
+    __ 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
index d504470..78cd069 100644 (file)
@@ -78,6 +78,14 @@ 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);
index fd26779..e148e2f 100644 (file)
@@ -406,6 +406,7 @@ static void PushInterceptorArguments(MacroAssembler* masm,
   __ push(receiver);
   __ push(holder);
   __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
+  __ push(Immediate(reinterpret_cast<int>(masm->isolate())));
 }
 
 
@@ -419,12 +420,12 @@ static void CompileCallLoadPropertyWithInterceptor(
   __ CallExternalReference(
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate()),
-      5);
+      6);
 }
 
 
 // Number of pointers to be reserved on stack for fast API call.
-static const int kFastApiCallArguments = 3;
+static const int kFastApiCallArguments = 4;
 
 
 // Reserves space for the extra arguments to API function in the
@@ -472,10 +473,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   //  -- esp[8]              : api function
   //                           (first fast api call extra argument)
   //  -- esp[12]             : api call data
-  //  -- esp[16]             : last argument
+  //  -- esp[16]             : isolate
+  //  -- esp[20]             : last argument
   //  -- ...
-  //  -- esp[(argc + 3) * 4] : first argument
-  //  -- esp[(argc + 4) * 4] : receiver
+  //  -- esp[(argc + 4) * 4] : first argument
+  //  -- esp[(argc + 5) * 4] : receiver
   // -----------------------------------
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
@@ -493,9 +495,11 @@ 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, 3 * kPointerSize));
+  __ lea(eax, Operand(esp, 4 * kPointerSize));
 
   const int kApiArgc = 1;  // API function gets reference to the v8::Arguments.
 
@@ -679,7 +683,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        5);
+        6);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -746,8 +750,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Register scratch,
                                       Label* miss_label) {
   // Check that the map of the object hasn't changed.
+  CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
+                                             : REQUIRE_EXACT_MAP;
   __ CheckMap(receiver_reg, Handle<Map>(object->map()),
-              miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+              miss_label, DO_SMI_CHECK, mode);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -1032,6 +1038,7 @@ 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.
@@ -1042,9 +1049,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
 
   __ push(scratch3);  // Restore return address.
 
-  // 3 elements array for v8::Arguments::values_, handler for name and pointer
+  // 4 elements array for v8::Arguments::values_, handler for name and pointer
   // to the values (it considered as smi in GC).
-  const int kStackSpace = 5;
+  const int kStackSpace = 6;
   const int kApiArgc = 2;
 
   __ PrepareCallApiFunction(kApiArgc);
@@ -1122,13 +1129,20 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
                                           name, miss);
     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
 
+    // Preserve the receiver register explicitly whenever it is different from
+    // the holder and it is needed should the interceptor return without any
+    // result. The CALLBACKS case needs the receiver to be passed into C++ code,
+    // the FIELD case might cause a miss during the prototype check.
+    bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
+    bool must_preserve_receiver_reg = !receiver.is(holder_reg) &&
+        (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+
     // Save necessary data before invoking an interceptor.
     // Requires a frame to make GC aware of pushed pointers.
     {
       FrameScope frame_scope(masm(), StackFrame::INTERNAL);
 
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-        // CALLBACKS case needs a receiver to be passed into C++ callback.
+      if (must_preserve_receiver_reg) {
         __ push(receiver);
       }
       __ push(holder_reg);
@@ -1151,10 +1165,17 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       frame_scope.GenerateLeaveFrame();
       __ ret(0);
 
+      // Clobber registers when generating debug-code to provoke errors.
       __ bind(&interceptor_failed);
+      if (FLAG_debug_code) {
+        __ mov(receiver, Immediate(BitCast<int32_t>(kZapValue)));
+        __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
+        __ mov(name_reg, Immediate(BitCast<int32_t>(kZapValue)));
+      }
+
       __ pop(name_reg);
       __ pop(holder_reg);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      if (must_preserve_receiver_reg) {
         __ pop(receiver);
       }
 
@@ -1163,7 +1184,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
 
     // Check that the maps from interceptor's holder to lookup's holder
     // haven't changed.  And load lookup's holder into holder_reg.
-    if (*interceptor_holder != lookup->holder()) {
+    if (must_perfrom_prototype_check) {
       holder_reg = CheckPrototypes(interceptor_holder,
                                    holder_reg,
                                    Handle<JSObject>(lookup->holder()),
@@ -1197,6 +1218,7 @@ 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
@@ -1204,7 +1226,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       ExternalReference ref =
           ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
                             masm()->isolate());
-      __ TailCallExternalReference(ref, 5, 1);
+      __ TailCallExternalReference(ref, 6, 1);
     }
   } else {  // !compile_followup_inline
     // Call the runtime system to load the interceptor.
@@ -1220,7 +1242,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
                           isolate());
-    __ TailCallExternalReference(ref, 5, 1);
+    __ TailCallExternalReference(ref, 6, 1);
   }
 }
 
@@ -2158,7 +2180,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
                   name, depth, &miss);
 
   // Move the return address on top of the stack.
-  __ mov(eax, Operand(esp, 3 * kPointerSize));
+  __ mov(eax, Operand(esp, 4 * kPointerSize));
   __ mov(Operand(esp, 0 * kPointerSize), eax);
 
   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
@@ -2687,27 +2709,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(eax, &miss);
+  __ JumpIfSmi(edx, &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, eax, last, ebx, edx, edi, name, &miss);
+  CheckPrototypes(object, edx, last, ebx, eax, 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, edx, &miss);
+        masm(), Handle<GlobalObject>::cast(last), name, eax, &miss);
   }
 
   // Return undefined if maps of the full prototype chain are still the
@@ -2728,13 +2750,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, eax, ebx, edx, edi, index, name, &miss);
+  GenerateLoadField(object, holder, edx, ebx, eax, edi, index, name, &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
@@ -2749,13 +2771,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, eax, ecx, ebx, edx, edi, callback,
+  GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, callback,
                        name, &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
@@ -2770,13 +2792,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, eax, ebx, edx, edi, value, name, &miss);
+  GenerateLoadConstant(object, holder, edx, ebx, eax, edi, value, name, &miss);
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
@@ -2789,8 +2811,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;
@@ -2800,7 +2822,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, eax, ecx, edx, ebx, edi,
+  GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi,
                           name, &miss);
 
   __ bind(&miss);
@@ -2818,15 +2840,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(eax, &miss);
-  CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss);
+  __ JumpIfSmi(edx, &miss);
+  CheckPrototypes(object, edx, holder, ebx, eax, edi, name, &miss);
 
   // Get the value from the cell.
   if (Serializer::enabled()) {
@@ -2864,7 +2886,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
                                                      Handle<JSObject> holder,
                                                      int index) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -2874,10 +2896,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
   __ IncrementCounter(counters->keyed_load_field(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
+  GenerateLoadField(receiver, holder, edx, ebx, eax, edi, index, name, &miss);
 
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_field(), 1);
@@ -2894,7 +2916,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
     Handle<JSObject> holder,
     Handle<AccessorInfo> callback) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -2904,10 +2926,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
   __ IncrementCounter(counters->keyed_load_callback(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, edi, callback,
+  GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, callback,
                        name, &miss);
 
   __ bind(&miss);
@@ -2925,7 +2947,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
     Handle<JSObject> holder,
     Handle<JSFunction> value) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -2935,11 +2957,11 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
   __ IncrementCounter(counters->keyed_load_constant_function(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
   GenerateLoadConstant(
-      receiver, holder, edx, ebx, ecx, edi, value, name, &miss);
+      receiver, holder, edx, ebx, eax, edi, value, name, &miss);
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_constant_function(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -2954,7 +2976,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
     Handle<JSObject> holder,
     Handle<String> name) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -2964,12 +2986,12 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
   __ IncrementCounter(counters->keyed_load_interceptor(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
   LookupResult lookup(isolate());
   LookupPostInterceptor(holder, name, &lookup);
-  GenerateLoadInterceptor(receiver, holder, &lookup, edx, eax, ecx, ebx, edi,
+  GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi,
                           name, &miss);
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_interceptor(), 1);
@@ -2983,7 +3005,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
     Handle<String> name) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -2993,10 +3015,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
   __ IncrementCounter(counters->keyed_load_array_length(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadArrayLength(masm(), edx, ecx, &miss);
+  GenerateLoadArrayLength(masm(), edx, eax, &miss);
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_array_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -3009,7 +3031,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
     Handle<String> name) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3019,10 +3041,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
   __ IncrementCounter(counters->keyed_load_string_length(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
+  GenerateLoadStringLength(masm(), edx, eax, ebx, &miss, true);
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_string_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -3035,7 +3057,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
     Handle<String> name) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3045,10 +3067,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
   __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
 
   // Check that the name has not changed.
-  __ cmp(eax, Immediate(name));
+  __ cmp(ecx, Immediate(name));
   __ j(not_equal, &miss);
 
-  GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
+  GenerateLoadFunctionPrototype(masm(), edx, eax, ebx, &miss);
   __ bind(&miss);
   __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@@ -3061,7 +3083,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
     Handle<Map> receiver_map) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3082,7 +3104,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
     MapHandleList* receiver_maps,
     CodeHandleList* handler_ics) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3246,7 +3268,7 @@ Handle<Code> ConstructStubCompiler::CompileConstructStub(
 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
     MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3254,21 +3276,15 @@ 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(eax, &miss_force_generic);
-  __ mov(ebx, eax);
+  __ JumpIfNotSmi(ecx, &miss_force_generic);
+  __ mov(ebx, ecx);
   __ SmiUntag(ebx);
-  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
+  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
 
   // Push receiver on the stack to free up a register for the dictionary
   // probing.
   __ push(edx);
-  __ LoadFromNumberDictionary(&slow,
-                              ecx,
-                              eax,
-                              ebx,
-                              edx,
-                              edi,
-                              eax);
+  __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax);
   // Pop receiver before returning.
   __ pop(edx);
   __ ret(0);
@@ -3277,7 +3293,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
   __ pop(edx);
 
   // ----------- S t a t e -------------
-  //  -- eax    : value
   //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
@@ -3289,7 +3304,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
 
   __ bind(&miss_force_generic);
   // ----------- S t a t e -------------
-  //  -- eax    : value
   //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
@@ -3301,11 +3315,44 @@ 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 -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3314,41 +3361,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.
-  __ JumpIfNotSmi(eax, &miss_force_generic);
+  // 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 index is in range.
   __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
-  __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset));
+  __ cmp(ecx, 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(eax);  // Untag the index.
-      __ movsx_b(eax, Operand(ebx, eax, times_1, 0));
+      __ SmiUntag(ecx);  // Untag the index.
+      __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
       break;
     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
     case EXTERNAL_PIXEL_ELEMENTS:
-      __ SmiUntag(eax);  // Untag the index.
-      __ movzx_b(eax, Operand(ebx, eax, times_1, 0));
+      __ SmiUntag(ecx);  // Untag the index.
+      __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
       break;
     case EXTERNAL_SHORT_ELEMENTS:
-      __ movsx_w(eax, Operand(ebx, eax, times_1, 0));
+      __ movsx_w(eax, Operand(ebx, ecx, times_1, 0));
       break;
     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-      __ movzx_w(eax, Operand(ebx, eax, times_1, 0));
+      __ movzx_w(eax, Operand(ebx, ecx, times_1, 0));
       break;
     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
     case EXTERNAL_INT_ELEMENTS:
-      __ mov(ecx, Operand(ebx, eax, times_2, 0));
+      __ mov(eax, Operand(ebx, ecx, times_2, 0));
       break;
     case EXTERNAL_FLOAT_ELEMENTS:
-      __ fld_s(Operand(ebx, eax, times_2, 0));
+      __ fld_s(Operand(ebx, ecx, times_2, 0));
       break;
     case EXTERNAL_DOUBLE_ELEMENTS:
-      __ fld_d(Operand(ebx, eax, times_4, 0));
+      __ fld_d(Operand(ebx, ecx, times_4, 0));
       break;
     default:
       UNREACHABLE();
@@ -3356,7 +3403,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
   }
 
   // For integer array types:
-  // ecx: value
+  // eax: value
   // For floating-point array type:
   // FP(0): value
 
@@ -3367,18 +3414,17 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     // it to a HeapNumber.
     Label box_int;
     if (elements_kind == EXTERNAL_INT_ELEMENTS) {
-      __ cmp(ecx, 0xC0000000);
+      __ cmp(eax, 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(ecx, Immediate(0xC0000000));
+      __ test(eax, Immediate(0xc0000000));
       __ j(not_zero, &box_int);
     }
 
-    __ mov(eax, ecx);
     __ SmiTag(eax);
     __ ret(0);
 
@@ -3387,33 +3433,31 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
     // Allocate a HeapNumber for the int and perform int-to-double
     // conversion.
     if (elements_kind == EXTERNAL_INT_ELEMENTS) {
-      __ push(ecx);
+      __ push(eax);
       __ fild_s(Operand(esp, 0));
-      __ pop(ecx);
+      __ pop(eax);
     } 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(ecx);
+      __ push(eax);
       __ fild_d(Operand(esp, 0));
-      __ pop(ecx);
-      __ pop(ecx);
+      __ pop(eax);
+      __ pop(eax);
     }
     // FP(0): value
-    __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
+    __ AllocateHeapNumber(eax, 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(ecx, ebx, edi, &failed_allocation);
+    __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation);
     // Set the value.
-    __ mov(eax, ecx);
     __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
     __ ret(0);
   } else {
@@ -3433,7 +3477,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
   __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
 
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3442,7 +3486,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3459,7 +3503,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
     MacroAssembler* masm,
     ElementsKind elements_kind) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- eax    : value
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3468,8 +3513,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.
-  __ JumpIfNotSmi(ecx, &miss_force_generic);
+  // 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 index is in range.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3564,12 +3609,39 @@ 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) {
+        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 {
           ASSERT(CpuFeatures::IsSupported(SSE2));
           CpuFeatures::Scope scope(SSE2);
           __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
-          // ecx: untagged integer value
+          __ cmp(ebx, 0x80000000u);
+          __ j(equal, &slow);
+          // ebx: untagged integer value
           switch (elements_kind) {
             case EXTERNAL_PIXEL_ELEMENTS:
               __ ClampUint8(ebx);
@@ -3583,41 +3655,14 @@ 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.
       }
@@ -3655,7 +3700,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
 
 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3664,19 +3709,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.
-  __ JumpIfNotSmi(eax, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
-  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
-  __ AssertFastElements(ecx);
+  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
+  __ AssertFastElements(eax);
 
   // Check that the key is within bounds.
-  __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
+  __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset));
   __ j(above_equal, &miss_force_generic);
 
   // Load the result and make sure it's not the hole.
-  __ mov(ebx, Operand(ecx, eax, times_2,
+  __ mov(ebx, Operand(eax, ecx, times_2,
                       FixedArray::kHeaderSize - kHeapObjectTag));
   __ cmp(ebx, masm->isolate()->factory()->the_hole_value());
   __ j(equal, &miss_force_generic);
@@ -3693,7 +3738,7 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) {
 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(
     MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- eax    : key
+  //  -- ecx    : key
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
@@ -3702,39 +3747,38 @@ 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.
-  __ JumpIfNotSmi(eax, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
-  __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
-  __ AssertFastElements(ecx);
+  __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
+  __ AssertFastElements(eax);
 
   // Check that the key is within bounds.
-  __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset));
+  __ cmp(ecx, FieldOperand(eax, FixedDoubleArray::kLengthOffset));
   __ j(above_equal, &miss_force_generic);
 
   // Check for the hole
   uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
-  __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32));
+  __ cmp(FieldOperand(eax, ecx, 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(ecx, eax, times_4,
+    __ movdbl(xmm0, FieldOperand(eax, ecx, times_4,
                                  FixedDoubleArray::kHeaderSize));
   } else {
-    __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize));
+    __ fld_d(FieldOperand(eax, ecx, times_4, FixedDoubleArray::kHeaderSize));
   }
-  __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber);
+  __ AllocateHeapNumber(eax, ebx, edi, &slow_allocate_heapnumber);
   // Set the value.
   if (CpuFeatures::IsSupported(SSE2)) {
     CpuFeatures::Scope use_sse2(SSE2);
-    __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0);
+    __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
   } else {
-    __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset));
+    __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   }
-  __ mov(eax, ecx);
   __ ret(0);
 
   __ bind(&slow_allocate_heapnumber);
@@ -3771,8 +3815,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.
-  __ JumpIfNotSmi(ecx, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
 
   if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
     __ JumpIfNotSmi(eax, &transition_elements_kind);
@@ -3926,8 +3970,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.
-  __ JumpIfNotSmi(ecx, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
@@ -3988,6 +4032,7 @@ 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));
 
index c762127..9772b94 100644 (file)
@@ -296,58 +296,44 @@ Failure* IC::ReferenceError(const char* type, Handle<String> name) {
 }
 
 
+static int ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state) {
+  bool was_uninitialized =
+      old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
+  bool is_uninitialized =
+      new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
+  return (was_uninitialized && !is_uninitialized) ?  1 :
+         (!was_uninitialized && is_uninitialized) ? -1 : 0;
+}
+
+
 void IC::PostPatching(Address address, Code* target, Code* old_target) {
-  if (FLAG_type_info_threshold > 0) {
-    if (old_target->is_inline_cache_stub() &&
-        target->is_inline_cache_stub()) {
-      State old_state = old_target->ic_state();
-      State new_state = target->ic_state();
-      bool was_uninitialized =
-          old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
-      bool is_uninitialized =
-          new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
-      int delta = 0;
-      if (was_uninitialized && !is_uninitialized) {
-        delta = 1;
-      } else if (!was_uninitialized && is_uninitialized) {
-        delta = -1;
-      }
-      if (delta != 0) {
-        Code* host = target->GetHeap()->isolate()->
-            inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
-        // Not all Code objects have TypeFeedbackInfo.
-        if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
-          TypeFeedbackInfo* info =
-              TypeFeedbackInfo::cast(host->type_feedback_info());
-          info->set_ic_with_typeinfo_count(
-              info->ic_with_typeinfo_count() + delta);
-        }
-      }
+  if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
+    return;
+  }
+  Code* host = target->GetHeap()->isolate()->
+      inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
+  if (host->kind() != Code::FUNCTION) return;
+
+  if (FLAG_type_info_threshold > 0 &&
+      old_target->is_inline_cache_stub() &&
+      target->is_inline_cache_stub()) {
+    int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
+                                          target->ic_state());
+    // Not all Code objects have TypeFeedbackInfo.
+    if (delta != 0 && host->type_feedback_info()->IsTypeFeedbackInfo()) {
+      TypeFeedbackInfo* info =
+          TypeFeedbackInfo::cast(host->type_feedback_info());
+      info->set_ic_with_type_info_count(
+          info->ic_with_type_info_count() + delta);
     }
   }
   if (FLAG_watch_ic_patching) {
+    host->set_profiler_ticks(0);
     Isolate::Current()->runtime_profiler()->NotifyICChanged();
-    // We do not want to optimize until the ICs have settled down,
-    // so when they are patched, we postpone optimization for the
-    // current function and the functions above it on the stack that
-    // might want to inline this one.
-    StackFrameIterator it;
-    if (it.done()) return;
-    it.Advance();
-    static const int kStackFramesToMark = Compiler::kMaxInliningLevels - 1;
-    for (int i = 0; i < kStackFramesToMark; ++i) {
-      if (it.done()) return;
-      StackFrame* raw_frame = it.frame();
-      if (raw_frame->is_java_script()) {
-        JSFunction* function =
-            JSFunction::cast(JavaScriptFrame::cast(raw_frame)->function());
-        if (function->IsOptimized()) continue;
-        SharedFunctionInfo* shared = function->shared();
-        shared->set_profiler_ticks(0);
-      }
-      it.Advance();
-    }
   }
+  // TODO(2029): When an optimized function is patched, it would
+  // be nice to propagate the corresponding type information to its
+  // unoptimized version for the benefit of later inlining.
 }
 
 
@@ -366,9 +352,9 @@ void IC::Clear(Address address) {
       return KeyedStoreIC::Clear(address, target);
     case Code::CALL_IC: return CallIC::Clear(address, target);
     case Code::KEYED_CALL_IC:  return KeyedCallIC::Clear(address, target);
+    case Code::COMPARE_IC: return CompareIC::Clear(address, target);
     case Code::UNARY_OP_IC:
     case Code::BINARY_OP_IC:
-    case Code::COMPARE_IC:
     case Code::TO_BOOLEAN_IC:
       // Clearing these is tricky and does not
       // make any performance difference.
@@ -379,9 +365,8 @@ void IC::Clear(Address address) {
 
 
 void CallICBase::Clear(Address address, Code* target) {
+  if (target->ic_state() == UNINITIALIZED) return;
   bool contextual = CallICBase::Contextual::decode(target->extra_ic_state());
-  State state = target->ic_state();
-  if (state == UNINITIALIZED) return;
   Code* code =
       Isolate::Current()->stub_cache()->FindCallInitialize(
           target->arguments_count(),
@@ -424,6 +409,17 @@ void KeyedStoreIC::Clear(Address address, Code* target) {
 }
 
 
+void CompareIC::Clear(Address address, Code* target) {
+  // Only clear ICCompareStubs, we currently cannot clear generic CompareStubs.
+  if (target->major_key() != CodeStub::CompareIC) return;
+  // Only clear CompareICs that can retain objects.
+  if (target->compare_state() != KNOWN_OBJECTS) return;
+  Token::Value op = CompareIC::ComputeOperation(target);
+  SetTargetAtAddress(address, GetRawUninitialized(op));
+  PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
+}
+
+
 static bool HasInterceptorGetter(JSObject* object) {
   return !object->GetNamedInterceptor()->getter()->IsUndefined();
 }
@@ -1067,18 +1063,33 @@ 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.
-  // 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();
-  }
+  // 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);
@@ -1775,6 +1786,10 @@ 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);
 
@@ -2391,7 +2406,7 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
 
     // Activate inlined smi code.
     if (previous_type == BinaryOpIC::UNINITIALIZED) {
-      PatchInlinedSmiCode(ic.address());
+      PatchInlinedSmiCode(ic.address(), ENABLE_INLINED_SMI_CHECK);
     }
   }
 
@@ -2452,6 +2467,14 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
 }
 
 
+Code* CompareIC::GetRawUninitialized(Token::Value op) {
+  ICCompareStub stub(op, UNINITIALIZED);
+  Code* code = NULL;
+  CHECK(stub.FindCodeInCache(&code));
+  return code;
+}
+
+
 Handle<Code> CompareIC::GetUninitialized(Token::Value op) {
   ICCompareStub stub(op, UNINITIALIZED);
   return stub.GetCode();
@@ -2466,6 +2489,12 @@ CompareIC::State CompareIC::ComputeState(Code* target) {
 }
 
 
+Token::Value CompareIC::ComputeOperation(Code* target) {
+  ASSERT(target->major_key() == CodeStub::CompareIC);
+  return static_cast<Token::Value>(target->compare_operation());
+}
+
+
 const char* CompareIC::GetStateName(State state) {
   switch (state) {
     case UNINITIALIZED: return "UNINITIALIZED";
index 5662552..3b44abf 100644 (file)
@@ -794,6 +794,9 @@ class CompareIC: public IC {
   // Helper function for determining the state of a compare IC.
   static State ComputeState(Code* target);
 
+  // Helper function for determining the operation a compare IC is for.
+  static Token::Value ComputeOperation(Code* target);
+
   static const char* GetStateName(State state);
 
  private:
@@ -804,7 +807,13 @@ class CompareIC: public IC {
   Condition GetCondition() const { return ComputeCondition(op_); }
   State GetState() { return ComputeState(target()); }
 
+  static Code* GetRawUninitialized(Token::Value op);
+
+  static void Clear(Address address, Code* target);
+
   Token::Value op_;
+
+  friend class IC;
 };
 
 
@@ -817,7 +826,8 @@ class ToBooleanIC: public IC {
 
 
 // Helper for BinaryOpIC and CompareIC.
-void PatchInlinedSmiCode(Address address);
+enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
 
 } }  // namespace v8::internal
 
index 3e3d6c4..5ce003f 100644 (file)
@@ -100,7 +100,7 @@ void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
   int64_t old_bytes_rescanned = bytes_rescanned_;
   bytes_rescanned_ = old_bytes_rescanned + obj_size;
   if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
-    if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSize()) {
+    if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) {
       // If we have queued twice the heap size for rescanning then we are
       // going around in circles, scanning the same objects again and again
       // as the program mutates the heap faster than we can incrementally
index 8fe89b4..5b58c9d 100644 (file)
@@ -205,6 +205,12 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
     MarkObject(target);
   }
 
+  void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
+    if (shared->ic_age() != heap_->global_ic_age()) {
+      shared->ResetForNewContext(heap_->global_ic_age());
+    }
+  }
+
   void VisitPointer(Object** p) {
     Object* obj = *p;
     if (obj->NonFailureIsHeapObject()) {
@@ -743,7 +749,7 @@ void IncrementalMarking::Finalize() {
 }
 
 
-void IncrementalMarking::MarkingComplete() {
+void IncrementalMarking::MarkingComplete(CompletionAction action) {
   state_ = COMPLETE;
   // We will set the stack guard to request a GC now.  This will mean the rest
   // of the GC gets performed as soon as possible (we can't do a GC here in a
@@ -754,13 +760,14 @@ void IncrementalMarking::MarkingComplete() {
   if (FLAG_trace_incremental_marking) {
     PrintF("[IncrementalMarking] Complete (normal).\n");
   }
-  if (!heap_->idle_notification_will_schedule_next_gc()) {
+  if (action == GC_VIA_STACK_GUARD) {
     heap_->isolate()->stack_guard()->RequestGC();
   }
 }
 
 
-void IncrementalMarking::Step(intptr_t allocated_bytes) {
+void IncrementalMarking::Step(intptr_t allocated_bytes,
+                              CompletionAction action) {
   if (heap_->gc_state() != Heap::NOT_IN_GC ||
       !FLAG_incremental_marking ||
       !FLAG_incremental_marking_steps ||
@@ -823,6 +830,19 @@ 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);
       }
@@ -833,7 +853,7 @@ void IncrementalMarking::Step(intptr_t allocated_bytes) {
       Marking::MarkBlack(obj_mark_bit);
       MemoryChunk::IncrementLiveBytesFromGC(obj->address(), size);
     }
-    if (marking_deque_.IsEmpty()) MarkingComplete();
+    if (marking_deque_.IsEmpty()) MarkingComplete(action);
   }
 
   allocated_ = 0;
@@ -931,7 +951,7 @@ void IncrementalMarking::ResetStepCounters() {
 
 
 int64_t IncrementalMarking::SpaceLeftInOldSpace() {
-  return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize();
+  return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects();
 }
 
 } }  // namespace v8::internal
index 4f8fa6b..8cbe6c1 100644 (file)
@@ -46,6 +46,11 @@ class IncrementalMarking {
     COMPLETE
   };
 
+  enum CompletionAction {
+    GC_VIA_STACK_GUARD,
+    NO_GC_VIA_STACK_GUARD
+  };
+
   explicit IncrementalMarking(Heap* heap);
 
   void TearDown();
@@ -82,7 +87,7 @@ class IncrementalMarking {
 
   void Abort();
 
-  void MarkingComplete();
+  void MarkingComplete(CompletionAction action);
 
   // It's hard to know how much work the incremental marker should do to make
   // progress in the face of the mutator creating new work for it.  We start
@@ -102,10 +107,11 @@ class IncrementalMarking {
   static const intptr_t kMaxAllocationMarkingFactor = 1000;
 
   void OldSpaceStep(intptr_t allocated) {
-    Step(allocated * kFastMarking / kInitialAllocationMarkingFactor);
+    Step(allocated * kFastMarking / kInitialAllocationMarkingFactor,
+         GC_VIA_STACK_GUARD);
   }
 
-  void Step(intptr_t allocated);
+  void Step(intptr_t allocated, CompletionAction action);
 
   inline void RestartIfNotMarking() {
     if (state_ == COMPLETE) {
index e344b86..7836110 100644 (file)
@@ -79,7 +79,7 @@ void Interface::DoAdd(
     PrintF("%*sthis = ", Nesting::current(), "");
     this->Print(Nesting::current());
     PrintF("%*s%s : ", Nesting::current(), "",
-           (*reinterpret_cast<String**>(name))->ToAsciiArray());
+           (*static_cast<String**>(name))->ToAsciiArray());
     interface->Print(Nesting::current());
   }
 #endif
@@ -97,7 +97,7 @@ void Interface::DoAdd(
 #ifdef DEBUG
     Nesting nested;
 #endif
-    reinterpret_cast<Interface*>(p->value)->Unify(interface, ok);
+    static_cast<Interface*>(p->value)->Unify(interface, ok);
   }
 
 #ifdef DEBUG
@@ -180,6 +180,15 @@ 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;
index c2991cb..580f082 100644 (file)
@@ -86,6 +86,12 @@ 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();
@@ -95,9 +101,6 @@ 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; }
 
@@ -110,6 +113,42 @@ 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
@@ -129,6 +168,7 @@ 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),
index b337e88..3a92b84 100644 (file)
@@ -33,8 +33,9 @@
 #include "utils.h"
 #include "ast.h"
 #include "bytecodes-irregexp.h"
-#include "jsregexp.h"
 #include "interpreter-irregexp.h"
+#include "jsregexp.h"
+#include "regexp-macro-assembler.h"
 
 namespace v8 {
 namespace internal {
@@ -449,6 +450,37 @@ 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) {
@@ -488,59 +520,6 @@ 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)]) {
index 625cc56..0c97abd 100644 (file)
@@ -38,7 +38,6 @@
 #include "heap-profiler.h"
 #include "hydrogen.h"
 #include "isolate.h"
-#include "lazy-instance.h"
 #include "lithium-allocator.h"
 #include "log.h"
 #include "messages.h"
 namespace v8 {
 namespace internal {
 
-struct GlobalState {
-  Thread::LocalStorageKey per_isolate_thread_data_key;
-  Thread::LocalStorageKey isolate_key;
-  Thread::LocalStorageKey thread_id_key;
-  Isolate* default_isolate;
-  Isolate::ThreadDataTable* thread_data_table;
-  Mutex* mutex;
-};
-
-struct InitializeGlobalState {
-  static void Construct(GlobalState* state) {
-    state->isolate_key = Thread::CreateThreadLocalKey();
-    state->thread_id_key = Thread::CreateThreadLocalKey();
-    state->per_isolate_thread_data_key = Thread::CreateThreadLocalKey();
-    state->thread_data_table = new Isolate::ThreadDataTable();
-    state->default_isolate = new Isolate();
-    state->mutex = OS::CreateMutex();
-    // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
-    // because a non-null thread data may be already set.
-    Thread::SetThreadLocal(state->isolate_key, state->default_isolate);
-  }
-};
-
-static LazyInstance<GlobalState, InitializeGlobalState>::type global_state;
-
 Atomic32 ThreadId::highest_thread_id_ = 0;
 
 int ThreadId::AllocateThreadId() {
@@ -91,11 +65,10 @@ int ThreadId::AllocateThreadId() {
 
 
 int ThreadId::GetCurrentThreadId() {
-  const GlobalState& global = global_state.Get();
-  int thread_id = Thread::GetThreadLocalInt(global.thread_id_key);
+  int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
   if (thread_id == 0) {
     thread_id = AllocateThreadId();
-    Thread::SetThreadLocalInt(global.thread_id_key, thread_id);
+    Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
   }
   return thread_id;
 }
@@ -339,16 +312,23 @@ void Isolate::PreallocatedStorageDelete(void* p) {
   storage->LinkTo(&free_list_);
 }
 
+Isolate* Isolate::default_isolate_ = NULL;
+Thread::LocalStorageKey Isolate::isolate_key_;
+Thread::LocalStorageKey Isolate::thread_id_key_;
+Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
+Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
+Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
+
+
 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
     ThreadId thread_id) {
   ASSERT(!thread_id.Equals(ThreadId::Invalid()));
   PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
   {
-    GlobalState* const global = global_state.Pointer();
-    ScopedLock lock(global->mutex);
-    ASSERT(global->thread_data_table->Lookup(this, thread_id) == NULL);
-    global->thread_data_table->Insert(per_thread);
-    ASSERT(global->thread_data_table->Lookup(this, thread_id) == per_thread);
+    ScopedLock lock(process_wide_mutex_);
+    ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL);
+    thread_data_table_->Insert(per_thread);
+    ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
   }
   return per_thread;
 }
@@ -359,9 +339,8 @@ Isolate::PerIsolateThreadData*
   ThreadId thread_id = ThreadId::Current();
   PerIsolateThreadData* per_thread = NULL;
   {
-    GlobalState* const global = global_state.Pointer();
-    ScopedLock lock(global->mutex);
-    per_thread = global->thread_data_table->Lookup(this, thread_id);
+    ScopedLock lock(process_wide_mutex_);
+    per_thread = thread_data_table_->Lookup(this, thread_id);
     if (per_thread == NULL) {
       per_thread = AllocatePerIsolateThreadData(thread_id);
     }
@@ -374,74 +353,64 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
   ThreadId thread_id = ThreadId::Current();
   PerIsolateThreadData* per_thread = NULL;
   {
-    GlobalState* const global = global_state.Pointer();
-    ScopedLock lock(global->mutex);
-    per_thread = global->thread_data_table->Lookup(this, thread_id);
+    ScopedLock lock(process_wide_mutex_);
+    per_thread = thread_data_table_->Lookup(this, thread_id);
   }
   return per_thread;
 }
 
 
-bool Isolate::IsDefaultIsolate() const {
-  return this == global_state.Get().default_isolate;
-}
-
-
 void Isolate::EnsureDefaultIsolate() {
-  GlobalState* const global = global_state.Pointer();
+  ScopedLock lock(process_wide_mutex_);
+  if (default_isolate_ == NULL) {
+    isolate_key_ = Thread::CreateThreadLocalKey();
+    thread_id_key_ = Thread::CreateThreadLocalKey();
+    per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
+    thread_data_table_ = new Isolate::ThreadDataTable();
+    default_isolate_ = new Isolate();
+  }
   // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
   // because a non-null thread data may be already set.
-  if (Thread::GetThreadLocal(global->isolate_key) == NULL) {
-    Thread::SetThreadLocal(global->isolate_key, global->default_isolate);
+  if (Thread::GetThreadLocal(isolate_key_) == NULL) {
+    Thread::SetThreadLocal(isolate_key_, default_isolate_);
   }
 }
 
+struct StaticInitializer {
+  StaticInitializer() {
+    Isolate::EnsureDefaultIsolate();
+  }
+} static_initializer;
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 Debugger* Isolate::GetDefaultIsolateDebugger() {
   EnsureDefaultIsolate();
-  return global_state.Pointer()->default_isolate->debugger();
+  return default_isolate_->debugger();
 }
 #endif
 
 
 StackGuard* Isolate::GetDefaultIsolateStackGuard() {
   EnsureDefaultIsolate();
-  return global_state.Pointer()->default_isolate->stack_guard();
-}
-
-
-Thread::LocalStorageKey Isolate::isolate_key() {
-  return global_state.Get().isolate_key;
-}
-
-
-Thread::LocalStorageKey Isolate::thread_id_key() {
-  return global_state.Get().thread_id_key;
-}
-
-
-Thread::LocalStorageKey Isolate::per_isolate_thread_data_key() {
-  return global_state.Get().per_isolate_thread_data_key;
+  return default_isolate_->stack_guard();
 }
 
 
 void Isolate::EnterDefaultIsolate() {
   EnsureDefaultIsolate();
-  Isolate* const default_isolate = global_state.Pointer()->default_isolate;
-  ASSERT(default_isolate != NULL);
+  ASSERT(default_isolate_ != NULL);
 
   PerIsolateThreadData* data = CurrentPerIsolateThreadData();
   // If not yet in default isolate - enter it.
-  if (data == NULL || data->isolate() != default_isolate) {
-    default_isolate->Enter();
+  if (data == NULL || data->isolate() != default_isolate_) {
+    default_isolate_->Enter();
   }
 }
 
 
 Isolate* Isolate::GetDefaultIsolateForLocking() {
   EnsureDefaultIsolate();
-  return global_state.Pointer()->default_isolate;
+  return default_isolate_;
 }
 
 
@@ -1461,6 +1430,7 @@ void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
 
 Isolate::Isolate()
     : state_(UNINITIALIZED),
+      embedder_data_(NULL),
       entry_stack_(NULL),
       stack_trace_nesting_level_(0),
       incomplete_message_(NULL),
@@ -1503,7 +1473,6 @@ Isolate::Isolate()
       string_tracker_(NULL),
       regexp_stack_(NULL),
       date_cache_(NULL),
-      embedder_data_(NULL),
       context_exit_happened_(false) {
   TRACE_ISOLATE(constructor);
 
@@ -1564,8 +1533,8 @@ void Isolate::TearDown() {
 
   Deinit();
 
-  { ScopedLock lock(global_state.Pointer()->mutex);
-    global_state.Pointer()->thread_data_table->RemoveAllThreads(this);
+  { ScopedLock lock(process_wide_mutex_);
+    thread_data_table_->RemoveAllThreads(this);
   }
 
   if (!IsDefaultIsolate()) {
@@ -1618,9 +1587,8 @@ void Isolate::Deinit() {
 
 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
                                      PerIsolateThreadData* data) {
-  const GlobalState& global = global_state.Get();
-  Thread::SetThreadLocal(global.isolate_key, isolate);
-  Thread::SetThreadLocal(global.per_isolate_thread_data_key, data);
+  Thread::SetThreadLocal(isolate_key_, isolate);
+  Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
 }
 
 
@@ -1874,6 +1842,9 @@ bool Isolate::Init(Deserializer* des) {
   // stack guard.
   heap_.SetStackLimits();
 
+  // Quiet the heap NaN if needed on target platform.
+  if (des != NULL) Assembler::QuietNaN(heap_.nan_value());
+
   deoptimizer_data_ = new DeoptimizerData;
   runtime_profiler_ = new RuntimeProfiler(this);
   runtime_profiler_->SetUp();
@@ -1886,6 +1857,13 @@ 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;
index 0c5a54c..f1c9b3c 100644 (file)
@@ -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 C
+#undef DECLARE_ENUM
     kIsolateAddressCount
   };
 
@@ -430,25 +430,19 @@ class Isolate {
   // not currently set).
   static PerIsolateThreadData* CurrentPerIsolateThreadData() {
     return reinterpret_cast<PerIsolateThreadData*>(
-        Thread::GetThreadLocal(per_isolate_thread_data_key()));
+        Thread::GetThreadLocal(per_isolate_thread_data_key_));
   }
 
   // Returns the isolate inside which the current thread is running.
   INLINE(static Isolate* Current()) {
-    const Thread::LocalStorageKey key = isolate_key();
     Isolate* isolate = reinterpret_cast<Isolate*>(
-        Thread::GetExistingThreadLocal(key));
-    if (!isolate) {
-      EnsureDefaultIsolate();
-      isolate = reinterpret_cast<Isolate*>(
-          Thread::GetExistingThreadLocal(key));
-    }
+        Thread::GetExistingThreadLocal(isolate_key_));
     ASSERT(isolate != NULL);
     return isolate;
   }
 
   INLINE(static Isolate* UncheckedCurrent()) {
-    return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key()));
+    return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
   }
 
   // Usually called by Init(), but can be called early e.g. to allow
@@ -470,7 +464,7 @@ class Isolate {
   // for legacy API reasons.
   void TearDown();
 
-  bool IsDefaultIsolate() const;
+  bool IsDefaultIsolate() const { return this == default_isolate_; }
 
   // Ensures that process-wide resources and the default isolate have been
   // allocated. It is only necessary to call this method in rare cases, for
@@ -495,10 +489,14 @@ class Isolate {
   // Returns the key used to store the pointer to the current isolate.
   // Used internally for V8 threads that do not execute JavaScript but still
   // are part of the domain of an isolate (like the context switcher).
-  static Thread::LocalStorageKey isolate_key();
+  static Thread::LocalStorageKey isolate_key() {
+    return isolate_key_;
+  }
 
   // Returns the key used to store process-wide thread IDs.
-  static Thread::LocalStorageKey thread_id_key();
+  static Thread::LocalStorageKey thread_id_key() {
+    return thread_id_key_;
+  }
 
   static Thread::LocalStorageKey per_isolate_thread_data_key();
 
@@ -1040,6 +1038,18 @@ 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 {
@@ -1082,19 +1092,21 @@ class Isolate {
     DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
   };
 
+  // This mutex protects highest_thread_id_, thread_data_table_ and
+  // default_isolate_.
+  static Mutex* process_wide_mutex_;
+
+  static Thread::LocalStorageKey per_isolate_thread_data_key_;
+  static Thread::LocalStorageKey isolate_key_;
+  static Thread::LocalStorageKey thread_id_key_;
+  static Isolate* default_isolate_;
+  static ThreadDataTable* thread_data_table_;
+
   void Deinit();
 
   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);
@@ -1138,13 +1150,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_;
@@ -1153,7 +1165,6 @@ class Isolate {
   Mutex* break_access_;
   Atomic32 debugger_initialized_;
   Mutex* debugger_access_;
-  Heap heap_;
   Logger* logger_;
   StackGuard stack_guard_;
   StatsTable* stats_table_;
@@ -1194,11 +1205,8 @@ 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.
index 8ccbae4..3455abc 100644 (file)
@@ -108,6 +108,60 @@ 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.
 
 
@@ -141,9 +195,14 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
     return Handle<Object>::null();
   }
 
-  if (parse_result.simple && !flags.is_ignore_case()) {
+  bool has_been_compiled = false;
+
+  if (parse_result.simple &&
+      !flags.is_ignore_case() &&
+      !HasFewDifferentCharacters(pattern)) {
     // 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) {
@@ -151,8 +210,12 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
     Vector<const uc16> atom_pattern = atom->data();
     Handle<String> atom_string =
         isolate->factory()->NewStringFromTwoByte(atom_pattern);
-    AtomCompile(re, pattern, flags, atom_string);
-  } else {
+    if (!HasFewDifferentCharacters(atom_string)) {
+      AtomCompile(re, pattern, flags, atom_string);
+      has_been_compiled = true;
+    }
+  }
+  if (!has_been_compiled) {
     IrregexpInitialize(re, pattern, flags, parse_result.capture_count);
   }
   ASSERT(re->data()->IsFixedArray());
@@ -280,7 +343,8 @@ 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, bool is_ascii) {
+bool RegExpImpl::EnsureCompiledIrregexp(
+    Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) {
   Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
 #ifdef V8_INTERPRETED_REGEXP
   if (compiled_code->IsByteArray()) return true;
@@ -296,7 +360,7 @@ bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) {
     ASSERT(compiled_code->IsSmi());
     return true;
   }
-  return CompileIrregexp(re, is_ascii);
+  return CompileIrregexp(re, sample_subject, is_ascii);
 }
 
 
@@ -316,7 +380,9 @@ static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
 }
 
 
-bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
+bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
+                                 Handle<String> sample_subject,
+                                 bool is_ascii) {
   // Compile the RegExp.
   Isolate* isolate = re->GetIsolate();
   ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
@@ -365,6 +431,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
                             flags.is_ignore_case(),
                             flags.is_multiline(),
                             pattern,
+                            sample_subject,
                             is_ascii);
   if (result.error_message != NULL) {
     // Unable to compile regexp.
@@ -435,7 +502,7 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
 
   // Check the asciiness of the underlying storage.
   bool is_ascii = subject->IsAsciiRepresentationUnderneath();
-  if (!EnsureCompiledIrregexp(regexp, is_ascii)) return -1;
+  if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1;
 
 #ifdef V8_INTERPRETED_REGEXP
   // Byte-code regexp needs space allocated for all its registers.
@@ -466,7 +533,7 @@ RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce(
 #ifndef V8_INTERPRETED_REGEXP
   ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
   do {
-    EnsureCompiledIrregexp(regexp, is_ascii);
+    EnsureCompiledIrregexp(regexp, subject, is_ascii);
     Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
     NativeRegExpMacroAssembler::Result res =
         NativeRegExpMacroAssembler::Match(code,
@@ -784,6 +851,53 @@ 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);
@@ -819,6 +933,7 @@ 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) {
@@ -837,6 +952,7 @@ class RegExpCompiler {
   bool ascii_;
   bool reg_exp_too_big_;
   int current_expansion_factor_;
+  FrequencyCollator frequency_collator_;
 };
 
 
@@ -865,7 +981,8 @@ 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) {
+      current_expansion_factor_(1),
+      frequency_collator_() {
   accept_ = new EndNode(EndNode::ACCEPT);
   ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
 }
@@ -1534,6 +1651,357 @@ 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,
@@ -1542,6 +2010,10 @@ 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;
@@ -1549,11 +2021,6 @@ 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;
@@ -1567,8 +2034,6 @@ 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) {
@@ -1578,6 +2043,18 @@ 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.
@@ -1597,64 +2074,43 @@ 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);
-  }
 
-  CharacterRange& range = ranges->at(last_valid_range);
-  uc16 from = range.from();
-  uc16 to = range.to();
+  // 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);
 
-  if (to > max_char) to = max_char;
-  ASSERT(to >= from);
+  bool zeroth_entry_is_failure = !cc->is_negated();
 
-  if (to == from) {
-    if (cc->is_negated()) {
-      macro_assembler->CheckCharacter(to, on_failure);
-    } else {
-      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);
-      }
+  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;
     } else {
-      if (cc->is_negated()) {
-        macro_assembler->GoTo(on_failure);
-      }
+      range_boundaries->Add(range.from());
     }
+    range_boundaries->Add(range.to() + 1);
   }
-  macro_assembler->Bind(&success);
+  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);
 }
 
 
@@ -1717,6 +2173,18 @@ int ActionNode::EatsAtLeast(int still_to_find,
 }
 
 
+void ActionNode::FillInBMInfo(int offset,
+                              BoyerMooreLookahead* bm,
+                              bool not_at_start) {
+  if (type_ == BEGIN_SUBMATCH) {
+    bm->SetRest(offset);
+  } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
+    on_success()->FillInBMInfo(offset, bm, not_at_start);
+  }
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
 int AssertionNode::EatsAtLeast(int still_to_find,
                                int recursion_depth,
                                bool not_at_start) {
@@ -1733,6 +2201,15 @@ int AssertionNode::EatsAtLeast(int still_to_find,
 }
 
 
+void AssertionNode::FillInBMInfo(
+    int offset, 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, bm, not_at_start);
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
 int BackReferenceNode::EatsAtLeast(int still_to_find,
                                    int recursion_depth,
                                    bool not_at_start) {
@@ -2071,10 +2548,12 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
     }
   }
   ASSERT(characters_filled_in != details->characters());
-  on_success()-> GetQuickCheckDetails(details,
-                                      compiler,
-                                      characters_filled_in,
-                                      true);
+  if (!details->cannot_match()) {
+    on_success()-> GetQuickCheckDetails(details,
+                                        compiler,
+                                        characters_filled_in,
+                                        true);
+  }
 }
 
 
@@ -2152,6 +2631,148 @@ 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,
@@ -2165,6 +2786,18 @@ void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
 }
 
 
+void LoopChoiceNode::FillInBMInfo(
+    int offset, BoyerMooreLookahead* bm, bool not_at_start) {
+  if (body_can_be_zero_length_) {
+    bm->SetRest(offset);
+    SaveBMInfo(bm, not_at_start, offset);
+    return;
+  }
+  ChoiceNode::FillInBMInfo(offset, bm, not_at_start);
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
                                       RegExpCompiler* compiler,
                                       int characters_filled_in,
@@ -2249,110 +2882,83 @@ static void EmitHat(RegExpCompiler* compiler,
 }
 
 
-// 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) {
+// Emit the code to handle \b and \B (word-boundary or non-word-boundary).
+void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
   RegExpMacroAssembler* assembler = compiler->macro_assembler();
-  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();
+  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, 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);
   }
-
-  assembler->Bind(&done);
-
-  on_success->Emit(compiler, &new_trace);
 }
 
 
-// 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) {
+void AssertionNode::BacktrackIfPrevious(
+    RegExpCompiler* compiler,
+    Trace* trace,
+    AssertionNode::IfPrevious backtrack_if_previous) {
   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 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 fall_through, dummy;
 
-  // 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);
+  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 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(boundary);
+    assembler->CheckAtStart(non_word);
   }
   // 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);
-  bool fall_through_on_word = (type == AssertionNode::AT_NON_BOUNDARY);
-  EmitWordCheck(assembler, not_boundary, boundary, fall_through_on_word);
+  assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, &dummy, false);
+  EmitWordCheck(assembler, word, non_word, backtrack_if_previous == kIsNonWord);
 
-  assembler->Bind(&ok);
-
-  on_success->Emit(compiler, &new_trace);
+  assembler->Bind(&fall_through);
+  on_success()->Emit(compiler, &new_trace);
 }
 
 
@@ -2400,13 +3006,9 @@ void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) {
       return;
     case AT_BOUNDARY:
     case AT_NON_BOUNDARY: {
-      EmitBoundaryCheck(type_, compiler, on_success(), trace);
+      EmitBoundaryCheck(compiler, trace);
       return;
     }
-    case AFTER_WORD_CHARACTER:
-    case AFTER_NONWORD_CHARACTER: {
-      EmitHalfBoundaryCheck(type_, compiler, on_success(), trace);
-    }
   }
   on_success()->Emit(compiler, trace);
 }
@@ -2661,6 +3263,30 @@ 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
@@ -2725,8 +3351,8 @@ void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
 
 
 int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler,
-                                           bool not_at_start) {
-  int preload_characters = EatsAtLeast(4, 0, not_at_start);
+                                           int eats_at_least) {
+  int preload_characters = Min(4, eats_at_least);
   if (compiler->macro_assembler()->CanReadUnaligned()) {
     bool ascii = compiler->ascii();
     if (ascii) {
@@ -2792,6 +3418,250 @@ 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
@@ -2870,7 +3740,6 @@ class AlternativeGenerationList {
  *        \______________/
  */
 
-
 void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
   RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
   int choice_count = alternatives_->length();
@@ -2935,10 +3804,52 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
 
   int first_normal_choice = greedy_loop ? 1 : 0;
 
-  int preload_characters =
-      CalculatePreloadCharacters(compiler,
-                                 current_trace->at_start() == Trace::FALSE);
-  bool preload_is_current =
+  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, 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 &&
       (current_trace->characters_preloaded() == preload_characters);
   bool preload_has_checked_bounds = preload_is_current;
 
@@ -3489,12 +4400,6 @@ 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);
@@ -3599,21 +4504,6 @@ 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);
@@ -3627,9 +4517,12 @@ RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
   return new TextNode(elements(), on_success);
 }
 
+
 static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
-                                 const uc16* special_class,
+                                 const int* 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);
@@ -3645,7 +4538,7 @@ static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
       return false;
     }
     range = ranges->at((i >> 1) + 1);
-    if (special_class[i+1] != range.from() - 1) {
+    if (special_class[i+1] != range.from()) {
       return false;
     }
   }
@@ -3657,14 +4550,17 @@ static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
 
 
 static bool CompareRanges(ZoneList<CharacterRange>* ranges,
-                          const uc16* special_class,
+                          const int* 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]) {
+    if (range.from() != special_class[i] ||
+        range.to() != special_class[i + 1] - 1) {
       return false;
     }
   }
@@ -4065,27 +4961,31 @@ RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler,
 }
 
 
-static void AddClass(const uc16* elmv,
+static void AddClass(const int* 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]));
+    ASSERT(elmv[i] < elmv[i + 1]);
+    ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1));
   }
 }
 
 
-static void AddClassNegated(const uc16 *elmv,
+static void AddClassNegated(const int *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] + 1;
+    last = elmv[i + 1];
   }
   ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit));
 }
@@ -4136,8 +5036,8 @@ void CharacterRange::AddClassEscape(uc16 type,
 }
 
 
-Vector<const uc16> CharacterRange::GetWordBounds() {
-  return Vector<const uc16>(kWordRanges, kWordRangeCount);
+Vector<const int> CharacterRange::GetWordBounds() {
+  return Vector<const int>(kWordRanges, kWordRangeCount - 1);
 }
 
 
@@ -4169,7 +5069,7 @@ void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) {
 
 
 void CharacterRange::Split(ZoneList<CharacterRange>* base,
-                           Vector<const uc16> overlay,
+                           Vector<const int> overlay,
                            ZoneList<CharacterRange>** included,
                            ZoneList<CharacterRange>** excluded) {
   ASSERT_EQ(NULL, *included);
@@ -4178,7 +5078,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]),
+    table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1),
                    CharacterRangeSplitter::kInOverlay);
   }
   CharacterRangeSplitter callback(included, excluded);
@@ -4226,7 +5126,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) {
@@ -4264,87 +5164,6 @@ 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) {
@@ -4477,145 +5296,6 @@ 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));
@@ -4639,45 +5319,6 @@ 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
 
@@ -4928,213 +5569,99 @@ 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);
-    }
-  }
-}
-
-
-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_;
 }
 
 
-int RegExpNode::ComputeFirstCharacterSet(int budget) {
-  // Default behavior is to not be able to determine the first character.
-  return kComputeFirstCharacterSetFail;
+void BackReferenceNode::FillInBMInfo(
+    int offset, 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);
 }
 
 
-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;
+STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
+              RegExpMacroAssembler::kTableSize);
 
-    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);
-    }
-  }
-  return budget;
-}
 
-
-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());
-    }
-  }
-  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;
-      }
+void ChoiceNode::FillInBMInfo(
+    int offset, BoyerMooreLookahead* bm, bool not_at_start) {
+  ZoneList<GuardedAlternative>* alts = alternatives();
+  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;
     }
+    alt.node()->FillInBMInfo(offset, bm, not_at_start);
   }
-  return budget;
+  SaveBMInfo(bm, not_at_start, offset);
 }
 
 
-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());
+void TextNode::FillInBMInfo(
+    int initial_offset, 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;
     }
-  }
-  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);
+    TextElement text = elements()->at(i);
     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);
+      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);
+        }
+      }
     } 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()) {
-        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);
+        bm->SetAll(offset);
       } else {
-        set_first_character_set(ranges);
+        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));
+        }
       }
+      offset++;
     }
   }
-  return budget;
+  if (offset >= bm->length()) {
+    if (initial_offset == 0) set_bm_info(not_at_start, bm);
+    return;
+  }
+  on_success()->FillInBMInfo(offset,
+                             bm,
+                             true);  // Not at start after a text node.
+  if (initial_offset == 0) set_bm_info(not_at_start, bm);
 }
 
 
-
 // -------------------------------------------------------------------
 // Dispatch table construction
 
@@ -5250,15 +5777,30 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) {
 }
 
 
-RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
-                                                      bool ignore_case,
-                                                      bool is_multiline,
-                                                      Handle<String> pattern,
-                                                      bool is_ascii) {
+RegExpEngine::CompilationResult RegExpEngine::Compile(
+    RegExpCompileData* data,
+    bool ignore_case,
+    bool is_multiline,
+    Handle<String> pattern,
+    Handle<String> sample_subject,
+    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,
@@ -5292,6 +5834,14 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
       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);
index 8875de9..20313ca 100644 (file)
@@ -40,6 +40,7 @@ class RegExpCompiler;
 class RegExpMacroAssembler;
 class RegExpNode;
 class RegExpTree;
+class BoyerMooreLookahead;
 
 class RegExpImpl {
  public:
@@ -190,8 +191,10 @@ class RegExpImpl {
   static String* last_ascii_string_;
   static String* two_byte_cached_string_;
 
-  static bool CompileIrregexp(Handle<JSRegExp> re, bool is_ascii);
-  static inline bool EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii);
+  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);
 
 
   // Set the subject cache.  The previous string buffer is not deleted, so the
@@ -222,48 +225,8 @@ enum ElementInSetsRelation {
 };
 
 
-// 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_;
-};
-
-
+// Represents code units in the range from from_ to to_, both ends are
+// inclusive.
 class CharacterRange {
  public:
   CharacterRange() : from_(0), to_(0) { }
@@ -271,7 +234,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 uc16> GetWordBounds();
+  static Vector<const int> GetWordBounds();
   static inline CharacterRange Singleton(uc16 value) {
     return CharacterRange(value, value);
   }
@@ -292,7 +255,7 @@ class CharacterRange {
   bool IsSingleton() { return (from_ == to_); }
   void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_ascii);
   static void Split(ZoneList<CharacterRange>* base,
-                    Vector<const uc16> overlay,
+                    Vector<const int> overlay,
                     ZoneList<CharacterRange>** included,
                     ZoneList<CharacterRange>** excluded);
   // Whether a range list is in canonical form: Ranges ordered by from value,
@@ -303,28 +266,6 @@ 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);
@@ -475,7 +416,8 @@ struct NodeInfo {
         follows_newline_interest(false),
         follows_start_interest(false),
         at_end(false),
-        visited(false) { }
+        visited(false),
+        replacement_calculated(false) { }
 
   // Returns true if the interests and assumptions of this node
   // matches the given one.
@@ -525,25 +467,7 @@ struct NodeInfo {
 
   bool at_end: 1;
   bool visited: 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_;
+  bool replacement_calculated: 1;
 };
 
 
@@ -599,9 +523,14 @@ class QuickCheckDetails {
 };
 
 
+extern int kUninitializedRegExpNodePlaceHolder;
+
+
 class RegExpNode: public ZoneObject {
  public:
-  RegExpNode() : first_character_set_(NULL), trace_count_(0) { }
+  RegExpNode() : replacement_(NULL), trace_count_(0) {
+    bm_info_[0] = bm_info_[1] = NULL;
+  }
   virtual ~RegExpNode();
   virtual void Accept(NodeVisitor* visitor) = 0;
   // Generates a goto to this node or actually generates the code at this point.
@@ -635,6 +564,45 @@ 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.
+  virtual void FillInBMInfo(
+      int offset, 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
@@ -645,72 +613,31 @@ class RegExpNode: public ZoneObject {
 
   NodeInfo* info() { return &info_; }
 
-  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;
+  BoyerMooreLookahead* bm_info(bool not_at_start) {
+    return bm_info_[not_at_start ? 1 : 0];
   }
 
  protected:
   enum LimitResult { DONE, CONTINUE };
-  static const int kComputeFirstCharacterSetFail = -1;
+  RegExpNode* replacement_;
 
   LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace);
 
-  // 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;
+  void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) {
+    bm_info_[not_at_start ? 1 : 0] = bm;
+  }
 
  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];
 };
 
 
@@ -731,8 +658,8 @@ class Interval {
     return (from_ <= value) && (value <= to_);
   }
   bool is_empty() { return from_ == kNone; }
-  int from() { return from_; }
-  int to() { return to_; }
+  int from() const { return from_; }
+  int to() const { return to_; }
   static Interval Empty() { return Interval(); }
   static const int kNone = -1;
  private:
@@ -747,6 +674,16 @@ 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, BoyerMooreLookahead* bm, bool not_at_start) {
+    on_success_->FillInBMInfo(offset, bm, not_at_start);
+    if (offset == 0) set_bm_info(not_at_start, bm);
+  }
+
+ protected:
+  RegExpNode* FilterSuccessor(int depth);
+
  private:
   RegExpNode* on_success_;
 };
@@ -793,11 +730,11 @@ class ActionNode: public SeqRegExpNode {
     return on_success()->GetQuickCheckDetails(
         details, compiler, filled_in, not_at_start);
   }
+  virtual void FillInBMInfo(
+      int offset, 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 {
@@ -860,13 +797,12 @@ class TextNode: public SeqRegExpNode {
   ZoneList<TextElement>* elements() { return elms_; }
   void MakeCaseIndependent(bool is_ascii);
   virtual int GreedyLoopTextLength();
-  virtual TextNode* Clone() {
-    TextNode* result = new TextNode(*this);
-    result->CalculateOffsets();
-    return result;
-  }
+  virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
+      RegExpCompiler* compiler);
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start);
   void CalculateOffsets();
-  virtual int ComputeFirstCharacterSet(int budget);
+  virtual RegExpNode* FilterASCII(int depth);
 
  private:
   enum TextEmitPassType {
@@ -897,12 +833,7 @@ class AssertionNode: public SeqRegExpNode {
     AT_START,
     AT_BOUNDARY,
     AT_NON_BOUNDARY,
-    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
+    AFTER_NEWLINE
   };
   static AssertionNode* AtEnd(RegExpNode* on_success) {
     return new AssertionNode(AT_END, on_success);
@@ -928,12 +859,17 @@ class AssertionNode: public SeqRegExpNode {
                                     RegExpCompiler* compiler,
                                     int filled_in,
                                     bool not_at_start);
-  virtual int ComputeFirstCharacterSet(int budget);
-  virtual AssertionNode* Clone() { return new AssertionNode(*this); }
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start);
   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_;
@@ -961,8 +897,8 @@ class BackReferenceNode: public SeqRegExpNode {
                                     bool not_at_start) {
     return;
   }
-  virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
-  virtual int ComputeFirstCharacterSet(int budget);
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start);
 
  private:
   int start_reg_;
@@ -986,7 +922,12 @@ class EndNode: public RegExpNode {
     // Returning 0 from EatsAtLeast should ensure we never get here.
     UNREACHABLE();
   }
-  virtual EndNode* Clone() { return new EndNode(*this); }
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start) {
+    // Returning 0 from EatsAtLeast should ensure we never get here.
+    UNREACHABLE();
+  }
+
  private:
   Action action_;
 };
@@ -1071,13 +1012,15 @@ class ChoiceNode: public RegExpNode {
                                     RegExpCompiler* compiler,
                                     int characters_filled_in,
                                     bool not_at_start);
-  virtual ChoiceNode* Clone() { return new ChoiceNode(*this); }
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start);
 
   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);
@@ -1089,7 +1032,7 @@ class ChoiceNode: public RegExpNode {
   void GenerateGuard(RegExpMacroAssembler* macro_assembler,
                      Guard* guard,
                      Trace* trace);
-  int CalculatePreloadCharacters(RegExpCompiler* compiler, bool not_at_start);
+  int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least);
   void EmitOutOfLineContinuation(RegExpCompiler* compiler,
                                  Trace* trace,
                                  GuardedAlternative alternative,
@@ -1119,13 +1062,18 @@ class NegativeLookaheadChoiceNode: public ChoiceNode {
                                     RegExpCompiler* compiler,
                                     int characters_filled_in,
                                     bool not_at_start);
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start) {
+    alternatives_->at(1).node()->FillInBMInfo(offset, 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 int ComputeFirstCharacterSet(int budget);
+  virtual RegExpNode* FilterASCII(int depth);
 };
 
 
@@ -1146,12 +1094,13 @@ class LoopChoiceNode: public ChoiceNode {
                                     RegExpCompiler* compiler,
                                     int characters_filled_in,
                                     bool not_at_start);
-  virtual int ComputeFirstCharacterSet(int budget);
-  virtual LoopChoiceNode* Clone() { return new LoopChoiceNode(*this); }
+  virtual void FillInBMInfo(
+      int offset, BoyerMooreLookahead* bm, bool not_at_start);
   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
@@ -1167,6 +1116,146 @@ 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
@@ -1458,6 +1547,7 @@ 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);
index 09dfe21..9d68b8c 100644 (file)
 //   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.
+//
 // Notes for advanced users:
 // LazyInstance can actually be used in two different ways:
 //
@@ -104,9 +111,17 @@ struct LeakyInstanceTrait {
 
 // Traits that define how an instance is allocated and accessed.
 
+// TODO(kalmard): __alignof__ is only defined for GCC > 4.2. Fix alignment issue
+// on MIPS with other compilers.
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
+#define LAZY_ALIGN(x) __attribute__((aligned(__alignof__(x))))
+#else
+#define LAZY_ALIGN(x)
+#endif
+
 template <typename T>
 struct StaticallyAllocatedInstanceTrait {
-  typedef char StorageType[sizeof(T)];
+  typedef char StorageType[sizeof(T)] LAZY_ALIGN(T);
 
   static T* MutableInstance(StorageType* storage) {
     return reinterpret_cast<T*>(storage);
@@ -118,6 +133,8 @@ struct StaticallyAllocatedInstanceTrait {
   }
 };
 
+#undef LAZY_ALIGN
+
 
 template <typename T>
 struct DynamicallyAllocatedInstanceTrait {
@@ -151,9 +168,29 @@ struct DefaultCreateTrait {
 };
 
 
+struct ThreadSafeInitOnceTrait {
+  template <typename Function, typename Storage>
+  static void Init(OnceType* once, Function function, Storage storage) {
+    CallOnce(once, function, storage);
+  }
+};
+
+
+// Initialization trait for users who don't care about thread-safety.
+struct SingleThreadInitOnceTrait {
+  template <typename Function, typename Storage>
+  static void Init(OnceType* once, Function function, Storage storage) {
+    if (*once == ONCE_STATE_UNINITIALIZED) {
+      function(storage);
+      *once = ONCE_STATE_DONE;
+    }
+  }
+};
+
+
 // TODO(pliard): Handle instances destruction (using global destructors).
 template <typename T, typename AllocationTrait, typename CreateTrait,
-          typename DestroyTrait  /* not used yet. */ >
+          typename InitOnceTrait, typename DestroyTrait  /* not used yet. */>
 struct LazyInstanceImpl {
  public:
   typedef typename AllocationTrait::StorageType StorageType;
@@ -164,7 +201,12 @@ struct LazyInstanceImpl {
   }
 
   void Init() const {
-    CallOnce(&once_, &InitInstance, &storage_);
+    InitOnceTrait::Init(
+        &once_,
+        // Casts to void* are needed here to avoid breaking strict aliasing
+        // rules.
+        reinterpret_cast<void(*)(void*)>(&InitInstance),  // NOLINT
+        reinterpret_cast<void*>(&storage_));
   }
 
  public:
@@ -180,35 +222,40 @@ struct LazyInstanceImpl {
 
   mutable OnceType once_;
   // Note that the previous field, OnceType, is an AtomicWord which guarantees
-  // the correct alignment of the storage field below.
+  // 4-byte alignment of the storage field below. If compiling with GCC (>4.2),
+  // the LAZY_ALIGN macro above will guarantee correctness for any alignment.
   mutable StorageType storage_;
 };
 
 
 template <typename T,
           typename CreateTrait = DefaultConstructTrait<T>,
+          typename InitOnceTrait = SingleThreadInitOnceTrait,
           typename DestroyTrait = LeakyInstanceTrait<T> >
 struct LazyStaticInstance {
-  typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, CreateTrait,
-      DestroyTrait> type;
+  typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>,
+      CreateTrait, InitOnceTrait, DestroyTrait> type;
 };
 
 
 template <typename T,
           typename CreateTrait = DefaultConstructTrait<T>,
+          typename InitOnceTrait = SingleThreadInitOnceTrait,
           typename DestroyTrait = LeakyInstanceTrait<T> >
 struct LazyInstance {
   // A LazyInstance is a LazyStaticInstance.
-  typedef typename LazyStaticInstance<T, CreateTrait, DestroyTrait>::type type;
+  typedef typename LazyStaticInstance<T, CreateTrait, InitOnceTrait,
+      DestroyTrait>::type type;
 };
 
 
 template <typename T,
-          typename CreateTrait = DefaultConstructTrait<T>,
+          typename CreateTrait = DefaultCreateTrait<T>,
+          typename InitOnceTrait = SingleThreadInitOnceTrait,
           typename DestroyTrait = LeakyInstanceTrait<T> >
 struct LazyDynamicInstance {
-  typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, CreateTrait,
-      DestroyTrait> type;
+  typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>,
+      CreateTrait, InitOnceTrait, DestroyTrait> type;
 };
 
 } }  // namespace v8::internal
index 7c2c83f..6cf3bad 100644 (file)
@@ -137,6 +137,14 @@ bool List<T, P>::RemoveElement(const T& elm) {
 
 
 template<typename T, class P>
+void List<T, P>::Allocate(int length) {
+  DeleteData(data_);
+  Initialize(length);
+  length_ = length;
+}
+
+
+template<typename T, class P>
 void List<T, P>::Clear() {
   DeleteData(data_);
   Initialize(0);
@@ -207,20 +215,19 @@ void List<T, P>::Initialize(int capacity) {
 }
 
 
-template <typename T>
-int SortedListBSearch(
-    const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)) {
+template <typename T, typename P>
+int SortedListBSearch(const List<T>& list, P cmp) {
   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, &elem) > 0) {
+    if (cmp(&mid_elem) > 0) {
       high = mid - 1;
       continue;
     }
-    if (cmp(&mid_elem, &elem) < 0) {
+    if (cmp(&mid_elem) < 0) {
       low = mid + 1;
       continue;
     }
@@ -231,9 +238,21 @@ int SortedListBSearch(
 }
 
 
+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>(list, elem, PointerValueCompare<T>);
+  return SortedListBSearch<T, ElementCmp<T> > (list, ElementCmp<T>(elem));
 }
 
 
index adddea4..7350c0d 100644 (file)
@@ -117,6 +117,9 @@ class List {
   // pointer type. Returns the removed element.
   INLINE(T RemoveLast()) { return Remove(length_ - 1); }
 
+  // Deletes current list contents and allocates space for 'length' elements.
+  INLINE(void Allocate(int length));
+
   // Clears the list by setting the length to zero. Even if T is a
   // pointer type, clearing the list doesn't delete the entries.
   INLINE(void Clear());
@@ -173,9 +176,11 @@ 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.
-template <typename T>
-int SortedListBSearch(
-    const List<T>& list, T elem, int (*cmp)(const T* x, const T* y));
+// |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);
 
index 4396c73..9534f9e 100644 (file)
@@ -958,7 +958,7 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
           }
         }
 
-        if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) {
+        if (instr->IsMarkedAsCall()) {
           for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
             if (output == NULL || !output->IsDoubleRegister() ||
                 output->index() != i) {
index aefd8b6..c41cce8 100644 (file)
@@ -95,31 +95,37 @@ void LOperand::PrintTo(StringStream* stream) {
 }
 
 #define DEFINE_OPERAND_CACHE(name, type)                      \
-  name* name::cache = NULL;                                   \
-  void name::SetUpCache() {                                   \
+  L##name* L##name::cache = NULL;                             \
+                                                              \
+  void L##name::SetUpCache() {                                \
     if (cache) return;                                        \
-    cache = new name[kNumCachedOperands];                     \
+    cache = new L##name[kNumCachedOperands];                  \
     for (int i = 0; i < kNumCachedOperands; i++) {            \
       cache[i].ConvertTo(type, i);                            \
     }                                                         \
   }                                                           \
+                                                              \
+  void L##name::TearDownCache() {                             \
+    delete[] 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)
-
+LITHIUM_OPERAND_LIST(DEFINE_OPERAND_CACHE)
 #undef DEFINE_OPERAND_CACHE
 
 void LOperand::SetUpCaches() {
-  LConstantOperand::SetUpCache();
-  LStackSlot::SetUpCache();
-  LDoubleStackSlot::SetUpCache();
-  LRegister::SetUpCache();
-  LDoubleRegister::SetUpCache();
+#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
 }
 
+
 bool LParallelMove::IsRedundant() const {
   for (int i = 0; i < move_operands_.length(); ++i) {
     if (!move_operands_[i].IsRedundant()) return false;
index d1e2e3c..2ccbf56 100644 (file)
 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 {
@@ -52,14 +60,13 @@ class LOperand: public ZoneObject {
 
   Kind kind() const { return KindField::decode(value_); }
   int index() const { return static_cast<int>(value_) >> kKindFieldWidth; }
-  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; }
+#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 Equals(LOperand* other) const { return value_ == other->value_; }
 
   void PrintTo(StringStream* stream);
@@ -69,9 +76,9 @@ class LOperand: public ZoneObject {
     ASSERT(this->index() == index);
   }
 
-  // Calls SetUpCache() for each subclass. Don't forget to update this method
-  // if you add a new LOperand subclass.
+  // Calls SetUpCache()/TearDownCache() for each subclass.
   static void SetUpCaches();
+  static void TearDownCaches();
 
  protected:
   static const int kKindFieldWidth = 3;
@@ -265,6 +272,7 @@ class LConstantOperand: public LOperand {
   }
 
   static void SetUpCache();
+  static void TearDownCache();
 
  private:
   static const int kNumCachedOperands = 128;
@@ -300,6 +308,7 @@ class LStackSlot: public LOperand {
   }
 
   static void SetUpCache();
+  static void TearDownCache();
 
  private:
   static const int kNumCachedOperands = 128;
@@ -324,6 +333,7 @@ class LDoubleStackSlot: public LOperand {
   }
 
   static void SetUpCache();
+  static void TearDownCache();
 
  private:
   static const int kNumCachedOperands = 128;
@@ -348,6 +358,7 @@ class LRegister: public LOperand {
   }
 
   static void SetUpCache();
+  static void TearDownCache();
 
  private:
   static const int kNumCachedOperands = 16;
@@ -372,6 +383,7 @@ class LDoubleRegister: public LOperand {
   }
 
   static void SetUpCache();
+  static void TearDownCache();
 
  private:
   static const int kNumCachedOperands = 16;
index abfb0f6..4463c93 100644 (file)
@@ -159,6 +159,11 @@ 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);
index 9c5294a..22b8250 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -30,6 +30,7 @@
 
 #include "liveedit.h"
 
+#include "code-stubs.h"
 #include "compilation-cache.h"
 #include "compiler.h"
 #include "debug.h"
@@ -1475,26 +1476,36 @@ static const char* DropFrames(Vector<StackFrame*> frames,
   // Check the nature of the top frame.
   Isolate* isolate = Isolate::Current();
   Code* pre_top_frame_code = pre_top_frame->LookupCode();
+  bool frame_has_padding;
   if (pre_top_frame_code->is_inline_cache_stub() &&
       pre_top_frame_code->ic_state() == DEBUG_BREAK) {
     // OK, we can drop inline cache calls.
     *mode = Debug::FRAME_DROPPED_IN_IC_CALL;
+    frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
   } else if (pre_top_frame_code ==
              isolate->debug()->debug_break_slot()) {
     // OK, we can drop debug break slot.
     *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
+    frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
   } else if (pre_top_frame_code ==
       isolate->builtins()->builtin(
           Builtins::kFrameDropper_LiveEdit)) {
     // OK, we can drop our own code.
     *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
+    frame_has_padding = false;
   } else if (pre_top_frame_code ==
       isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
     *mode = Debug::FRAME_DROPPED_IN_RETURN_CALL;
+    frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
   } else if (pre_top_frame_code->kind() == Code::STUB &&
-      pre_top_frame_code->major_key()) {
-    // Entry from our unit tests, it's fine, we support this case.
+      pre_top_frame_code->major_key() == CodeStub::CEntry) {
+    // Entry from our unit tests on 'debugger' statement.
+    // It's fine, we support this case.
     *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
+    // We don't have a padding from 'debugger' statement call.
+    // Here the stub is CEntry, it's not debug-only and can't be padded.
+    // If anyone would complain, a proxy padded stub could be added.
+    frame_has_padding = false;
   } else {
     return "Unknown structure of stack above changing function";
   }
@@ -1504,8 +1515,49 @@ static const char* DropFrames(Vector<StackFrame*> frames,
       - Debug::kFrameDropperFrameSize * kPointerSize  // Size of the new frame.
       + kPointerSize;  // Bigger address end is exclusive.
 
+  Address* top_frame_pc_address = top_frame->pc_address();
+
+  // top_frame may be damaged below this point. Do not used it.
+  ASSERT(!(top_frame = NULL));
+
   if (unused_stack_top > unused_stack_bottom) {
-    return "Not enough space for frame dropper frame";
+    if (frame_has_padding) {
+      int shortage_bytes =
+          static_cast<int>(unused_stack_top - unused_stack_bottom);
+
+      Address padding_start = pre_top_frame->fp() -
+          Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize;
+
+      Address padding_pointer = padding_start;
+      Smi* padding_object =
+          Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue);
+      while (Memory::Object_at(padding_pointer) == padding_object) {
+        padding_pointer -= kPointerSize;
+      }
+      int padding_counter =
+          Smi::cast(Memory::Object_at(padding_pointer))->value();
+      if (padding_counter * kPointerSize < shortage_bytes) {
+        return "Not enough space for frame dropper frame "
+            "(even with padding frame)";
+      }
+      Memory::Object_at(padding_pointer) =
+          Smi::FromInt(padding_counter - shortage_bytes / kPointerSize);
+
+      StackFrame* pre_pre_frame = frames[top_frame_index - 2];
+
+      memmove(padding_start + kPointerSize - shortage_bytes,
+          padding_start + kPointerSize,
+          Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize);
+
+      pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes);
+      pre_pre_frame->SetCallerFp(pre_top_frame->fp());
+      unused_stack_top -= shortage_bytes;
+
+      STATIC_ASSERT(sizeof(Address) == kPointerSize);
+      top_frame_pc_address -= shortage_bytes / kPointerSize;
+    } else {
+      return "Not enough space for frame dropper frame";
+    }
   }
 
   // Committing now. After this point we should return only NULL value.
@@ -1515,7 +1567,7 @@ static const char* DropFrames(Vector<StackFrame*> frames,
   ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
 
   Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit();
-  top_frame->set_pc(code->entry());
+  *top_frame_pc_address = code->entry();
   pre_top_frame->SetCallerFp(bottom_js_frame->fp());
 
   *restarter_frame_function_pointer =
index 21d64df..d93a9d8 100644 (file)
@@ -1730,13 +1730,20 @@ void Logger::EnableSlidingStateWindow() {
 }
 
 // Protects the state below.
-static LazyMutex active_samplers_mutex = LAZY_MUTEX_INITIALIZER;
+static Mutex* active_samplers_mutex = NULL;
 
 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.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   for (int i = 0;
        ActiveSamplersExist() && i < active_samplers_->length();
        ++i) {
@@ -1763,7 +1770,7 @@ SamplerRegistry::State SamplerRegistry::GetState() {
 
 void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
   ASSERT(sampler->IsActive());
-  ScopedLock lock(active_samplers_mutex.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   if (active_samplers_ == NULL) {
     active_samplers_ = new List<Sampler*>;
   } else {
@@ -1775,7 +1782,7 @@ void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
 
 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) {
   ASSERT(sampler->IsActive());
-  ScopedLock lock(active_samplers_mutex.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   ASSERT(active_samplers_ != NULL);
   bool removed = active_samplers_->RemoveElement(sampler);
   ASSERT(removed);
index 1297387..03c7b3b 100644 (file)
@@ -437,6 +437,8 @@ class SamplerRegistry : public AllStatic {
     HAS_CPU_PROFILING_SAMPLERS
   };
 
+  static void SetUp();
+
   typedef void (*VisitSampler)(Sampler*, void*);
 
   static State GetState();
index 93287ae..08fa82e 100644 (file)
@@ -196,6 +196,7 @@ 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]);
 
@@ -204,6 +205,15 @@ 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;
index dde172d..0aa1192 100644 (file)
@@ -296,8 +296,6 @@ void MarkCompactCollector::CollectGarbage() {
 
   if (!collect_maps_) ReattachInitialMaps();
 
-  heap_->isolate()->inner_pointer_to_code_cache()->Flush();
-
   Finish();
 
   tracer_ = NULL;
@@ -337,6 +335,7 @@ 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
@@ -373,6 +372,7 @@ void MarkCompactCollector::ClearMarkbits() {
     MarkBit mark_bit = Marking::MarkBitFrom(obj);
     mark_bit.Clear();
     mark_bit.Next().Clear();
+    Page::FromAddress(obj->address())->ResetLiveBytes();
   }
 }
 
@@ -680,7 +680,6 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
 
   ASSERT(!FLAG_never_compact || !FLAG_always_compact);
 
-  if (collect_maps_) CreateBackPointers();
 #ifdef ENABLE_GDB_JIT_INTERFACE
   if (FLAG_gdbjit) {
     // If GDBJIT interface is active disable compaction.
@@ -1150,9 +1149,10 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object);
 
     // Enqueue weak map in linked list of encountered weak maps.
-    ASSERT(weak_map->next() == Smi::FromInt(0));
-    weak_map->set_next(collector->encountered_weak_maps());
-    collector->set_encountered_weak_maps(weak_map);
+    if (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);
@@ -1168,9 +1168,15 @@ class StaticMarkingVisitor : public StaticVisitorBase {
         object_size);
 
     // Mark the backing hash table without pushing it on the marking stack.
-    ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
-    ASSERT(!MarkCompactCollector::IsMarked(table));
-    collector->SetMark(table, Marking::MarkBitFrom(table));
+    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.
     collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map()));
     ASSERT(MarkCompactCollector::IsMarked(table->map()));
   }
@@ -1179,16 +1185,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     Heap* heap = map->GetHeap();
     Code* code = reinterpret_cast<Code*>(object);
     if (FLAG_cleanup_code_caches_at_gc) {
-      Object* raw_info = code->type_feedback_info();
-      if (raw_info->IsTypeFeedbackInfo()) {
-        TypeFeedbackCells* type_feedback_cells =
-            TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
-        for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
-          ASSERT(type_feedback_cells->AstId(i)->IsSmi());
-          JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
-          cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
-        }
-      }
+      code->ClearTypeFeedbackCells(heap);
     }
     code->CodeIterateBody<StaticMarkingVisitor>(heap);
   }
@@ -1390,6 +1387,12 @@ 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);
@@ -1519,12 +1522,6 @@ 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,
@@ -1818,13 +1815,19 @@ void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) {
 void MarkCompactCollector::MarkMapContents(Map* map) {
   // Mark prototype transitions array but don't push it into marking stack.
   // This will make references from it weak. We will clean dead prototype
-  // transitions in ClearNonLiveTransitions.
-  FixedArray* prototype_transitions = map->prototype_transitions();
-  MarkBit mark = Marking::MarkBitFrom(prototype_transitions);
-  if (!mark.Get()) {
-    mark.Set();
-    MemoryChunk::IncrementLiveBytesFromGC(prototype_transitions->address(),
-                                          prototype_transitions->Size());
+  // transitions in ClearNonLiveTransitions. But make sure that back pointers
+  // stored inside prototype transitions arrays are marked.
+  Object* raw_proto_transitions = map->unchecked_prototype_transitions();
+  if (raw_proto_transitions->IsFixedArray()) {
+    FixedArray* prototype_transitions = FixedArray::cast(raw_proto_transitions);
+    MarkBit mark = Marking::MarkBitFrom(prototype_transitions);
+    if (!mark.Get()) {
+      mark.Set();
+      MemoryChunk::IncrementLiveBytesFromGC(prototype_transitions->address(),
+                                            prototype_transitions->Size());
+      MarkObjectAndPush(HeapObject::cast(
+          prototype_transitions->get(Map::kProtoTransitionBackPointerOffset)));
+    }
   }
 
   Object** raw_descriptor_array_slot =
@@ -1923,23 +1926,6 @@ void MarkCompactCollector::MarkDescriptorArray(
 }
 
 
-void MarkCompactCollector::CreateBackPointers() {
-  HeapObjectIterator iterator(heap()->map_space());
-  for (HeapObject* next_object = iterator.Next();
-       next_object != NULL; next_object = iterator.Next()) {
-    if (next_object->IsMap()) {  // Could also be FreeSpace object on free list.
-      Map* map = Map::cast(next_object);
-      STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
-      if (map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
-        map->CreateBackPointers();
-      } else {
-        ASSERT(map->instance_descriptors() == heap()->empty_descriptor_array());
-      }
-    }
-  }
-}
-
-
 // Fill the marking stack with overflowed objects returned by the given
 // iterator.  Stop when the marking stack is filled or the end of the space
 // is reached, whichever comes first.
@@ -1970,6 +1956,7 @@ 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);
@@ -2462,15 +2449,8 @@ void MarkCompactCollector::ReattachInitialMaps() {
 void MarkCompactCollector::ClearNonLiveTransitions() {
   HeapObjectIterator map_iterator(heap()->map_space());
   // Iterate over the map space, setting map transitions that go from
-  // a marked map to an unmarked map to null transitions.  At the same time,
-  // set all the prototype fields of maps back to their original value,
-  // dropping the back pointers temporarily stored in the prototype field.
-  // Setting the prototype field requires following the linked list of
-  // back pointers, reversing them all at once.  This allows us to find
-  // those maps with map transitions that need to be nulled, and only
-  // scan the descriptor arrays of those maps, not all maps.
-  // All of these actions are carried out only on maps of JSObjects
-  // and related subtypes.
+  // a marked map to an unmarked map to null transitions.  This action
+  // is carried out only on maps of JSObjects and related subtypes.
   for (HeapObject* obj = map_iterator.Next();
        obj != NULL; obj = map_iterator.Next()) {
     Map* map = reinterpret_cast<Map*>(obj);
@@ -2546,36 +2526,16 @@ void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
 
 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
                                                       MarkBit map_mark) {
-  // Follow the chain of back pointers to find the prototype.
-  Object* real_prototype = map;
-  while (real_prototype->IsMap()) {
-    real_prototype = Map::cast(real_prototype)->prototype();
-    ASSERT(real_prototype->IsHeapObject());
-  }
+  Object* potential_parent = map->GetBackPointer();
+  if (!potential_parent->IsMap()) return;
+  Map* parent = Map::cast(potential_parent);
 
-  // Follow back pointers, setting them to prototype, clearing map transitions
-  // when necessary.
-  Map* current = map;
+  // Follow back pointer, check whether we are dealing with a map transition
+  // from a live map to a dead path and in case clear transitions of parent.
   bool current_is_alive = map_mark.Get();
-  bool on_dead_path = !current_is_alive;
-  while (current->IsMap()) {
-    Object* next = current->prototype();
-    // There should never be a dead map above a live map.
-    ASSERT(on_dead_path || current_is_alive);
-
-    // A live map above a dead map indicates a dead transition. This test will
-    // always be false on the first iteration.
-    if (on_dead_path && current_is_alive) {
-      on_dead_path = false;
-      current->ClearNonLiveTransitions(heap(), real_prototype);
-    }
-
-    Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset);
-    *slot = real_prototype;
-    if (current_is_alive) RecordSlot(slot, slot, real_prototype);
-
-    current = reinterpret_cast<Map*>(next);
-    current_is_alive = Marking::MarkBitFrom(current).Get();
+  bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
+  if (!current_is_alive && parent_is_alive) {
+    parent->ClearNonLiveTransitions(heap());
   }
 }
 
@@ -2586,14 +2546,17 @@ 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* value = table->get(table->EntryToValueIndex(i));
-        StaticMarkingVisitor::VisitPointer(heap(), &value);
-        table->set_unchecked(heap(),
-                             table->EntryToValueIndex(i),
-                             value,
-                             UPDATE_WRITE_BARRIER);
+        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);
       }
     }
     weak_map_obj = weak_map->next();
@@ -3413,6 +3376,8 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
   // under it.
   ProcessInvalidatedCode(&updating_visitor);
 
+  heap_->isolate()->inner_pointer_to_code_cache()->Flush();
+
 #ifdef DEBUG
   if (FLAG_verify_heap) {
     VerifyEvacuation(heap_);
@@ -3825,7 +3790,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
   bool lazy_sweeping_active = false;
   bool unused_page_present = false;
 
-  intptr_t old_space_size = heap()->PromotedSpaceSize();
+  intptr_t old_space_size = heap()->PromotedSpaceSizeOfObjects();
   intptr_t space_left =
       Min(heap()->OldGenPromotionLimit(old_space_size),
           heap()->OldGenAllocationLimit(old_space_size)) - old_space_size;
index 66ffd19..6420a21 100644 (file)
@@ -544,6 +544,8 @@ class MarkCompactCollector {
 
   void ClearMarkbits();
 
+  bool is_compacting() const { return compacting_; }
+
  private:
   MarkCompactCollector();
   ~MarkCompactCollector();
@@ -640,13 +642,6 @@ class MarkCompactCollector {
 
   void ProcessNewlyMarkedObject(HeapObject* obj);
 
-  // Creates back pointers for all map transitions, stores them in
-  // the prototype field.  The original prototype pointers are restored
-  // in ClearNonLiveTransitions().  All JSObject maps
-  // connected by map transitions have the same prototype object, which
-  // is why we can use this field temporarily for back pointers.
-  void CreateBackPointers();
-
   // Mark a Map and its DescriptorArray together, skipping transitions.
   void MarkMapContents(Map* map);
   void MarkAccessorPairSlot(HeapObject* accessors, int offset);
index 8e735c4..aee56af 100644 (file)
@@ -30,7 +30,6 @@
 // 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
index a3adcf8..f8b5766 100644 (file)
@@ -1125,13 +1125,7 @@ function SetUpError() {
     }
     %FunctionSetInstanceClassName(f, 'Error');
     %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
-    // The name property on the prototype of error objects is not
-    // specified as being read-one and dont-delete. However, allowing
-    // overwriting allows leaks of error objects between script blocks
-    // in the same context in a browser setting. Therefore we fix the
-    // name.
-    %SetProperty(f.prototype, "name", name,
-                 DONT_ENUM | DONT_DELETE | READ_ONLY)  ;
+    %SetProperty(f.prototype, "name", name, DONT_ENUM);
     %SetCode(f, function(m) {
       if (%_IsConstructCall()) {
         // Define all the expected properties directly on the error
@@ -1147,10 +1141,8 @@ function SetUpError() {
               return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
           });
         } else if (!IS_UNDEFINED(m)) {
-          %IgnoreAttributesAndSetProperty(this,
-                                          'message',
-                                          ToString(m),
-                                          DONT_ENUM);
+          %IgnoreAttributesAndSetProperty(
+            this, 'message', ToString(m), DONT_ENUM);
         }
         captureStackTrace(this, f);
       } else {
@@ -1180,16 +1172,41 @@ $Error.captureStackTrace = captureStackTrace;
 var visited_errors = new InternalArray();
 var cyclic_error_marker = new $Object();
 
+function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
+  // Climb the prototype chain until we find the holder.
+  while (error && !%HasLocalProperty(error, name)) {
+    error = error.__proto__;
+  }
+  if (error === null) return void 0;
+  if (!IS_OBJECT(error)) return error[name];
+  // If the property is an accessor on one of the predefined errors that can be
+  // generated statically by the compiler, don't touch it. This is to address
+  // http://code.google.com/p/chromium/issues/detail?id=69187
+  var desc = %GetOwnProperty(error, name);
+  if (desc && desc[IS_ACCESSOR_INDEX]) {
+    var isName = name === "name";
+    if (error === $ReferenceError.prototype)
+      return isName ? "ReferenceError" : void 0;
+    if (error === $SyntaxError.prototype)
+      return isName ? "SyntaxError" : void 0;
+    if (error === $TypeError.prototype)
+      return isName ? "TypeError" : void 0;
+  }
+  // Otherwise, read normally.
+  return error[name];
+}
+
 function ErrorToStringDetectCycle(error) {
   if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
   try {
-    var type = error.type;
-    var name = error.name;
+    var type = GetPropertyWithoutInvokingMonkeyGetters(error, "type");
+    var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name");
     name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
-    var message = error.message;
+    var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message");
     var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty);
     if (type && !hasMessage) {
-      message = FormatMessage(%NewMessageObject(type, error.arguments));
+      var args = GetPropertyWithoutInvokingMonkeyGetters(error, "arguments");
+      message = FormatMessage(%NewMessageObject(type, args));
     }
     message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message);
     if (name === "") return message;
index 0d7f921..f347fdc 100644 (file)
@@ -143,7 +143,7 @@ int ToNumber(Register reg) {
     27,   // k1
     28,   // gp
     29,   // sp
-    30,   // s8_fp
+    30,   // fp
     31,   // ra
   };
   return kNumbers[reg.code()];
@@ -163,7 +163,7 @@ Register ToRegister(int num) {
     k0, k1,
     gp,
     sp,
-    s8_fp,
+    fp,
     ra
   };
   return kRegisters[num];
@@ -237,28 +237,28 @@ MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
 static const int kNegOffset = 0x00008000;
 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
 // operations as post-increment of sp.
-const Instr kPopInstruction = ADDIU | (sp.code() << kRsShift)
-      | (sp.code() << kRtShift) | (kPointerSize & kImm16Mask);
+const Instr kPopInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift) | (kPointerSize & kImm16Mask);
 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
-const Instr kPushInstruction = ADDIU | (sp.code() << kRsShift)
-      | (sp.code() << kRtShift) | (-kPointerSize & kImm16Mask);
+const Instr kPushInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift) | (-kPointerSize & kImm16Mask);
 // sw(r, MemOperand(sp, 0))
-const Instr kPushRegPattern = SW | (sp.code() << kRsShift)
+const Instr kPushRegPattern = SW | (kRegister_sp_Code << kRsShift)
       |  (0 & kImm16Mask);
 //  lw(r, MemOperand(sp, 0))
-const Instr kPopRegPattern = LW | (sp.code() << kRsShift)
+const Instr kPopRegPattern = LW | (kRegister_sp_Code << kRsShift)
       |  (0 & kImm16Mask);
 
-const Instr kLwRegFpOffsetPattern = LW | (s8_fp.code() << kRsShift)
+const Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
       |  (0 & kImm16Mask);
 
-const Instr kSwRegFpOffsetPattern = SW | (s8_fp.code() << kRsShift)
+const Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
       |  (0 & kImm16Mask);
 
-const Instr kLwRegFpNegOffsetPattern = LW | (s8_fp.code() << kRsShift)
+const Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
       |  (kNegOffset & kImm16Mask);
 
-const Instr kSwRegFpNegOffsetPattern = SW | (s8_fp.code() << kRsShift)
+const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
       |  (kNegOffset & kImm16Mask);
 // A mask for the Rt register for push, pop, lw, sw instructions.
 const Instr kRtMask = kRtFieldMask;
@@ -2137,6 +2137,15 @@ Address Assembler::target_address_at(Address pc) {
 }
 
 
+// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
+// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
+// snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
+// OS::nan_value() returns a qNaN.
+void Assembler::QuietNaN(HeapObject* object) {
+  HeapNumber::cast(object)->set_value(OS::nan_value());
+}
+
+
 // On Mips, a target address is stored in a lui/ori instruction pair, each
 // of which load 16 bits of the 32-bit address to a register.
 // Patching the address must replace both instr, and flush the i-cache.
index 8b877f6..84714e5 100644 (file)
@@ -125,40 +125,59 @@ struct Register {
   int code_;
 };
 
-const Register no_reg = { -1 };
-
-const Register zero_reg = { 0 };  // Always zero.
-const Register at = { 1 };   // at: Reserved for synthetic instructions.
-const Register v0 = { 2 };   // v0, v1: Used when returning multiple values
-const Register v1 = { 3 };   //   from subroutines.
-const Register a0 = { 4 };   // a0 - a4: Used to pass non-FP parameters.
-const Register a1 = { 5 };
-const Register a2 = { 6 };
-const Register a3 = { 7 };
-const Register t0 = { 8 };   // t0 - t9: Can be used without reservation, act
-const Register t1 = { 9 };   //   as temporary registers and are allowed to
-const Register t2 = { 10 };  //   be destroyed by subroutines.
-const Register t3 = { 11 };
-const Register t4 = { 12 };
-const Register t5 = { 13 };
-const Register t6 = { 14 };
-const Register t7 = { 15 };
-const Register s0 = { 16 };  // s0 - s7: Subroutine register variables.
-const Register s1 = { 17 };  //   Subroutines that write to these registers
-const Register s2 = { 18 };  //   must restore their values before exiting so
-const Register s3 = { 19 };  //   that the caller can expect the values to be
-const Register s4 = { 20 };  //   preserved.
-const Register s5 = { 21 };
-const Register s6 = { 22 };
-const Register s7 = { 23 };
-const Register t8 = { 24 };
-const Register t9 = { 25 };
-const Register k0 = { 26 };  // k0, k1: Reserved for system calls and
-const Register k1 = { 27 };  // interrupt handlers.
-const Register gp = { 28 };  // gp: Reserved.
-const Register sp = { 29 };  // sp: Stack pointer.
-const Register s8_fp = { 30 };  // fp: Frame pointer.
-const Register ra = { 31 };  // ra: Return address pointer.
+#define REGISTER(N, C) \
+  const int kRegister_ ## N ## _Code = C; \
+  const Register N = { C }
+
+REGISTER(no_reg, -1);
+// Always zero.
+REGISTER(zero_reg, 0);
+// at: Reserved for synthetic instructions.
+REGISTER(at, 1);
+// v0, v1: Used when returning multiple values from subroutines.
+REGISTER(v0, 2);
+REGISTER(v1, 3);
+// a0 - a4: Used to pass non-FP parameters.
+REGISTER(a0, 4);
+REGISTER(a1, 5);
+REGISTER(a2, 6);
+REGISTER(a3, 7);
+// t0 - t9: Can be used without reservation, act as temporary registers and are
+// allowed to be destroyed by subroutines.
+REGISTER(t0, 8);
+REGISTER(t1, 9);
+REGISTER(t2, 10);
+REGISTER(t3, 11);
+REGISTER(t4, 12);
+REGISTER(t5, 13);
+REGISTER(t6, 14);
+REGISTER(t7, 15);
+// s0 - s7: Subroutine register variables. Subroutines that write to these
+// registers must restore their values before exiting so that the caller can
+// expect the values to be preserved.
+REGISTER(s0, 16);
+REGISTER(s1, 17);
+REGISTER(s2, 18);
+REGISTER(s3, 19);
+REGISTER(s4, 20);
+REGISTER(s5, 21);
+REGISTER(s6, 22);
+REGISTER(s7, 23);
+REGISTER(t8, 24);
+REGISTER(t9, 25);
+// k0, k1: Reserved for system calls and interrupt handlers.
+REGISTER(k0, 26);
+REGISTER(k1, 27);
+// gp: Reserved.
+REGISTER(gp, 28);
+// sp: Stack pointer.
+REGISTER(sp, 29);
+// fp: Frame pointer.
+REGISTER(fp, 30);
+// ra: Return address pointer.
+REGISTER(ra, 31);
+
+#undef REGISTER
 
 
 int ToNumber(Register reg);
@@ -303,7 +322,6 @@ static const Register& kLithiumScratchReg = s3;  // Scratch register.
 static const Register& kLithiumScratchReg2 = s4;  // Scratch register.
 static const Register& kRootRegister = s6;  // Roots array pointer.
 static const Register& cp = s7;     // JavaScript context pointer.
-static const Register& fp = s8_fp;  // Alias for fp.
 static const DoubleRegister& kLithiumScratchDouble = f30;
 static const FPURegister& kDoubleRegZero = f28;
 
@@ -552,6 +570,8 @@ class Assembler : public AssemblerBase {
 
   static void JumpLabelToJumpRegister(Address pc);
 
+  static void QuietNaN(HeapObject* nan);
+
   // This sets the branch destination (which gets loaded at the call address).
   // This is for calls and branches within generated code.  The serializer
   // has already deserialized the lui/ori instructions etc.
index 1b3242c..f3dd95b 100644 (file)
@@ -481,7 +481,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
   __ Branch(&not_special, gt, source_, Operand(1));
 
   // For 1 or -1 we need to or in the 0 exponent (biased to 1023).
-  static const uint32_t exponent_word_for_1 =
+  const uint32_t exponent_word_for_1 =
       HeapNumber::kExponentBias << HeapNumber::kExponentShift;
   // Safe to use 'at' as dest reg here.
   __ Or(at, exponent, Operand(exponent_word_for_1));
@@ -2754,7 +2754,6 @@ void BinaryOpStub::GenerateSmiCode(
   Register left = a1;
   Register right = a0;
   Register scratch1 = t3;
-  Register scratch2 = t5;
 
   // Perform combined smi check on both operands.
   __ Or(scratch1, left, Operand(right));
@@ -3459,7 +3458,6 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
 
     Label no_update;
     Label skip_cache;
-    const Register heap_number_map = t2;
 
     // Call C function to calculate the result and update the cache.
     // Register a0 holds precalculated cache entry address; preserve
@@ -4421,7 +4419,7 @@ Register InstanceofStub::right() { return a1; }
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   // The displacement is the offset of the last parameter (if any)
   // relative to the frame pointer.
-  static const int kDisplacement =
+  const int kDisplacement =
       StandardFrameConstants::kCallerSPOffset - kPointerSize;
 
   // Check that the key is a smiGenerateReadElement.
@@ -4833,10 +4831,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   //  sp[8]: subject string
   //  sp[12]: JSRegExp object
 
-  static const int kLastMatchInfoOffset = 0 * kPointerSize;
-  static const int kPreviousIndexOffset = 1 * kPointerSize;
-  static const int kSubjectOffset = 2 * kPointerSize;
-  static const int kJSRegExpOffset = 3 * kPointerSize;
+  const int kLastMatchInfoOffset = 0 * kPointerSize;
+  const int kPreviousIndexOffset = 1 * kPointerSize;
+  const int kSubjectOffset = 2 * kPointerSize;
+  const int kJSRegExpOffset = 3 * kPointerSize;
 
   Isolate* isolate = masm->isolate();
 
@@ -5045,8 +5043,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
                       1, a0, a2);
 
   // Isolates: note we add an additional parameter here (isolate pointer).
-  static const int kRegExpExecuteArguments = 8;
-  static const int kParameterRegisters = 4;
+  const int kRegExpExecuteArguments = 8;
+  const int kParameterRegisters = 4;
   __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
 
   // Stack pointer now points to cell where return address is to be written.
@@ -5402,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(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-    __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
-    __ sw(a2, MemOperand(sp, argc_ * kPointerSize));
+    __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+    __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset));
+    __ sw(a3, MemOperand(sp, argc_ * kPointerSize));
     __ bind(&call);
   }
 
@@ -5412,8 +5410,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
   // a1: pushed function (to be verified)
   __ JumpIfSmi(a1, &non_function);
   // Get the map of the function object.
-  __ GetObjectType(a1, a2, a2);
-  __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE));
+  __ GetObjectType(a1, a3, a3);
+  __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
+
+  if (RecordCallTarget()) {
+    GenerateRecordCallTarget(masm);
+  }
 
   // Fast-case: Invoke the function now.
   // a1: pushed function
@@ -5438,8 +5440,17 @@ 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, a2, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ Branch(&non_function, ne, a3, 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));
@@ -5931,7 +5942,7 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
   // scratch: -
 
   // Perform a number of probes in the symbol table.
-  static const int kProbes = 4;
+  const int kProbes = 4;
   Label found_in_symbol_table;
   Label next_probe[kProbes];
   Register candidate = scratch5;  // Scratch register contains candidate.
@@ -6059,9 +6070,9 @@ void SubStringStub::Generate(MacroAssembler* masm) {
   //  0 <= from <= to <= string.length.
   // If any of these assumptions fail, we call the runtime system.
 
-  static const int kToOffset = 0 * kPointerSize;
-  static const int kFromOffset = 1 * kPointerSize;
-  static const int kStringOffset = 2 * kPointerSize;
+  const int kToOffset = 0 * kPointerSize;
+  const int kFromOffset = 1 * kPointerSize;
+  const int kStringOffset = 2 * kPointerSize;
 
   __ lw(a2, MemOperand(sp, kToOffset));
   __ lw(a3, MemOperand(sp, kFromOffset));
@@ -6095,37 +6106,11 @@ 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));
-
-
-  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);
+  // 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.
 
   // Deal with different string types: update the index if necessary
   // and put the underlying string into t1.
@@ -7356,43 +7341,46 @@ struct AheadOfTimeWriteBarrierStubList {
   RememberedSetAction action;
 };
 
+#define REG(Name) { kRegister_ ## Name ## _Code }
 
-struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
+static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
   // Used in RegExpExecStub.
-  { s2, s0, t3, EMIT_REMEMBERED_SET },
-  { s2, a2, t3, EMIT_REMEMBERED_SET },
+  { REG(s2), REG(s0), REG(t3), EMIT_REMEMBERED_SET },
+  { REG(s2), REG(a2), REG(t3), EMIT_REMEMBERED_SET },
   // Used in CompileArrayPushCall.
   // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore.
   // Also used in KeyedStoreIC::GenerateGeneric.
-  { a3, t0, t1, EMIT_REMEMBERED_SET },
+  { REG(a3), REG(t0), REG(t1), EMIT_REMEMBERED_SET },
   // Used in CompileStoreGlobal.
-  { t0, a1, a2, OMIT_REMEMBERED_SET },
+  { REG(t0), REG(a1), REG(a2), OMIT_REMEMBERED_SET },
   // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField.
-  { a1, a2, a3, EMIT_REMEMBERED_SET },
-  { a3, a2, a1, EMIT_REMEMBERED_SET },
+  { REG(a1), REG(a2), REG(a3), EMIT_REMEMBERED_SET },
+  { REG(a3), REG(a2), REG(a1), EMIT_REMEMBERED_SET },
   // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField.
-  { a2, a1, a3, EMIT_REMEMBERED_SET },
-  { a3, a1, a2, EMIT_REMEMBERED_SET },
+  { REG(a2), REG(a1), REG(a3), EMIT_REMEMBERED_SET },
+  { REG(a3), REG(a1), REG(a2), EMIT_REMEMBERED_SET },
   // KeyedStoreStubCompiler::GenerateStoreFastElement.
-  { a3, a2, t0, EMIT_REMEMBERED_SET },
-  { a2, a3, t0, EMIT_REMEMBERED_SET },
+  { REG(a3), REG(a2), REG(t0), EMIT_REMEMBERED_SET },
+  { REG(a2), REG(a3), REG(t0), EMIT_REMEMBERED_SET },
   // ElementsTransitionGenerator::GenerateSmiOnlyToObject
   // and ElementsTransitionGenerator::GenerateSmiOnlyToDouble
   // and ElementsTransitionGenerator::GenerateDoubleToObject
-  { a2, a3, t5, EMIT_REMEMBERED_SET },
-  { a2, a3, t5, OMIT_REMEMBERED_SET },
+  { REG(a2), REG(a3), REG(t5), EMIT_REMEMBERED_SET },
+  { REG(a2), REG(a3), REG(t5), OMIT_REMEMBERED_SET },
   // ElementsTransitionGenerator::GenerateDoubleToObject
-  { t2, a2, a0, EMIT_REMEMBERED_SET },
-  { a2, t2, t5, EMIT_REMEMBERED_SET },
+  { REG(t2), REG(a2), REG(a0), EMIT_REMEMBERED_SET },
+  { REG(a2), REG(t2), REG(t5), EMIT_REMEMBERED_SET },
   // StoreArrayLiteralElementStub::Generate
-  { t1, a0, t2, EMIT_REMEMBERED_SET },
+  { REG(t1), REG(a0), REG(t2), EMIT_REMEMBERED_SET },
   // Null termination.
-  { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET}
+  { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET}
 };
 
+#undef REG
+
 
 bool RecordWriteStub::IsPregenerated() {
-  for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
+  for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
        !entry->object.is(no_reg);
        entry++) {
     if (object_.is(entry->object) &&
@@ -7419,7 +7407,7 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime() {
 
 
 void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() {
-  for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
+  for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
        !entry->object.is(no_reg);
        entry++) {
     RecordWriteStub stub(entry->object,
index fd04722..3d58571 100644 (file)
@@ -788,11 +788,6 @@ 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_
index 83f5f50..3be1e4d 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -116,6 +116,8 @@ void BreakLocationIterator::ClearDebugBreakAtSlot() {
                      Assembler::kDebugBreakSlotInstructions);
 }
 
+const bool Debug::FramePaddingLayout::kIsSupported = false;
+
 
 #define __ ACCESS_MASM(masm)
 
index 51c2e46..62f3155 100644 (file)
@@ -447,6 +447,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -454,7 +456,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 7 * kPointerSize;
+  unsigned fixed_frame_size = 8 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -519,6 +521,15 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08x: [top + %d] <- 0x%08x ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
@@ -549,8 +560,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   uint32_t pc = reinterpret_cast<uint32_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
index 657bee8..4ffd0ea 100644 (file)
@@ -120,13 +120,6 @@ 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
@@ -282,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) {
-        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);
+        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);
       }
       VisitDeclarations(scope()->declarations());
     }
@@ -796,64 +789,53 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
 }
 
 
-void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
-                                        VariableMode mode,
-                                        FunctionLiteral* function) {
+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) {
   // 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 binding_needs_init = (function == NULL) &&
-      (mode == CONST || mode == CONST_HARMONY || mode == LET);
+  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_->Add(variable->name());
+      globals_->Add(variable->binding_needs_init()
+                        ? isolate()->factory()->the_hole_value()
+                        : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
     case Variable::LOCAL:
-      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));
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+        __ sw(t0, StackOperand(variable));
       }
       break;
 
       case Variable::CONTEXT:
-      // 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");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        EmitDebugCheckDeclarationContext(variable);
           __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
           __ sw(at, ContextOperand(cp, variable->index()));
           // No write barrier since the_hole_value is in old space.
@@ -862,13 +844,11 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       break;
 
     case Variable::LOOKUP: {
-      Comment cmnt(masm_, "[ Declaration");
+      Comment cmnt(masm_, "[ VariableDeclaration");
       __ li(a2, Operand(variable->name()));
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR ||
-             mode == CONST ||
-             mode == CONST_HARMONY ||
-             mode == LET);
+      ASSERT(mode == VAR || mode == LET ||
+             mode == CONST || mode == CONST_HARMONY);
       PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
         ? READ_ONLY : NONE;
       __ li(a1, Operand(Smi::FromInt(attr)));
@@ -876,13 +856,9 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       // 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 (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);
+      if (hole_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.
@@ -895,6 +871,122 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
 }
 
 
+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.
@@ -2296,6 +2388,18 @@ 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);
@@ -2984,7 +3088,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, MemOperand(s0, HeapNumber::kValueOffset - kHeapObjectTag));
+    __ sdc1(f0, FieldMemOperand(s0, HeapNumber::kValueOffset));
     __ mov(v0, s0);
   } else {
     __ PrepareCallCFunction(2, a0);
@@ -3646,7 +3750,6 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
   Register scratch1 = t3;
   Register scratch2 = t5;
   Register scratch3 = t4;
-  Register scratch4 = v1;
 
   // Separator operand is on the stack.
   __ pop(separator);
@@ -4492,7 +4595,8 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope()) {
+  if (declaration_scope->is_global_scope() ||
+      declaration_scope->is_module_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
index 2c4da1a..964a7e2 100644 (file)
@@ -767,7 +767,7 @@ static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
   __ Branch(slow_case, lt, scratch2, Operand(FIRST_JS_RECEIVER_TYPE));
 
   // Check that the key is a positive smi.
-  __ And(scratch1, key, Operand(0x8000001));
+  __ And(scratch1, key, Operand(0x80000001));
   __ Branch(slow_case, ne, scratch1, Operand(zero_reg));
 
   // Load the elements into scratch1 and check its map.
@@ -1688,12 +1688,12 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
 
   // Activate inlined smi code.
   if (previous_state == UNINITIALIZED) {
-    PatchInlinedSmiCode(address());
+    PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
   }
 }
 
 
-void PatchInlinedSmiCode(Address address) {
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
   Address andi_instruction_address =
       address + Assembler::kCallTargetAddressOffset;
 
@@ -1727,33 +1727,30 @@ void PatchInlinedSmiCode(Address address) {
   Instr instr_at_patch = Assembler::instr_at(patch_address);
   Instr branch_instr =
       Assembler::instr_at(patch_address + Instruction::kInstrSize);
-  ASSERT(Assembler::IsAndImmediate(instr_at_patch));
-  ASSERT_EQ(0, Assembler::GetImmediate16(instr_at_patch));
+  // This is patching a conditional "jump if not smi/jump if smi" site.
+  // Enabling by changing from
+  //   andi at, rx, 0
+  //   Branch <target>, eq, at, Operand(zero_reg)
+  // to:
+  //   andi at, rx, #kSmiTagMask
+  //   Branch <target>, ne, at, Operand(zero_reg)
+  // and vice-versa to be disabled again.
+  CodePatcher patcher(patch_address, 2);
+  Register reg = Register::from_code(Assembler::GetRs(instr_at_patch));
+  if (check == ENABLE_INLINED_SMI_CHECK) {
+    ASSERT(Assembler::IsAndImmediate(instr_at_patch));
+    ASSERT_EQ(0, Assembler::GetImmediate16(instr_at_patch));
+    patcher.masm()->andi(at, reg, kSmiTagMask);
+  } else {
+    ASSERT(check == DISABLE_INLINED_SMI_CHECK);
+    ASSERT(Assembler::IsAndImmediate(instr_at_patch));
+    patcher.masm()->andi(at, reg, 0);
+  }
   ASSERT(Assembler::IsBranch(branch_instr));
   if (Assembler::IsBeq(branch_instr)) {
-    // This is patching a "jump if not smi" site to be active.
-    // Changing:
-    //   andi at, rx, 0
-    //   Branch <target>, eq, at, Operand(zero_reg)
-    // to:
-    //   andi at, rx, #kSmiTagMask
-    //   Branch <target>, ne, at, Operand(zero_reg)
-    CodePatcher patcher(patch_address, 2);
-    Register reg = Register::from_code(Assembler::GetRs(instr_at_patch));
-    patcher.masm()->andi(at, reg, kSmiTagMask);
     patcher.ChangeBranchCondition(ne);
   } else {
     ASSERT(Assembler::IsBne(branch_instr));
-    // This is patching a "jump if smi" site to be active.
-    // Changing:
-    //   andi at, rx, 0
-    //   Branch <target>, ne, at, Operand(zero_reg)
-    // to:
-    //   andi at, rx, #kSmiTagMask
-    //   Branch <target>, eq, at, Operand(zero_reg)
-    CodePatcher patcher(patch_address, 2);
-    Register reg = Register::from_code(Assembler::GetRs(instr_at_patch));
-    patcher.masm()->andi(at, reg, kSmiTagMask);
     patcher.ChangeBranchCondition(eq);
   }
 }
index 6628d8e..986921f 100644 (file)
@@ -2139,8 +2139,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                   RelocInfo::CODE_TARGET,
                   instr,
                   RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
-  ASSERT(instr->HasDeoptimizationEnvironment());
-  LEnvironment* env = instr->deoptimization_environment();
+  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
   safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
   // Put the result value into the result register slot and
   // restore all registers.
@@ -2345,39 +2344,35 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
   int map_count = instr->hydrogen()->types()->length();
+  bool need_generic = instr->hydrogen()->need_generic();
+
+  if (map_count == 0 && !need_generic) {
+    DeoptimizeIf(al, instr->environment());
+    return;
+  }
   Handle<String> name = instr->hydrogen()->name();
-  if (map_count == 0) {
-    ASSERT(instr->hydrogen()->need_generic());
-    __ li(a2, Operand(name));
-    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  } else {
-    Label done;
-    __ lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
-    for (int i = 0; i < map_count - 1; ++i) {
-      Handle<Map> map = instr->hydrogen()->types()->at(i);
+  Label done;
+  __ lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  for (int i = 0; i < map_count; ++i) {
+    bool last = (i == map_count - 1);
+    Handle<Map> map = instr->hydrogen()->types()->at(i);
+    if (last && !need_generic) {
+      Handle<Map> map = instr->hydrogen()->types()->last();
+      DeoptimizeIf(ne, instr->environment(), scratch, Operand(map));
+    } else {
       Label next;
       __ Branch(&next, ne, scratch, Operand(map));
       EmitLoadFieldOrConstantFunction(result, object, map, name);
       __ Branch(&done);
       __ bind(&next);
     }
-    Handle<Map> map = instr->hydrogen()->types()->last();
-    if (instr->hydrogen()->need_generic()) {
-      Label generic;
-      __ Branch(&generic, ne, scratch, Operand(map));
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-      __ Branch(&done);
-      __ bind(&generic);
-      __ li(a2, Operand(name));
-      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      CallCode(ic, RelocInfo::CODE_TARGET, instr);
-    } else {
-      DeoptimizeIf(ne, instr->environment(), scratch, Operand(map));
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-    }
-    __ bind(&done);
   }
+  if (need_generic) {
+    __ li(a2, Operand(name));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  }
+  __ bind(&done);
 }
 
 
@@ -2651,16 +2646,20 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
   Register temp = scratch1();
   Register result = ToRegister(instr->result());
 
-  // 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).
+  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).
+  }
 }
 
 
@@ -2768,7 +2767,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
   __ sll(scratch, length, 2);
 
   __ bind(&invoke);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -2793,6 +2792,11 @@ 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());
@@ -2823,7 +2827,6 @@ void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
 
 
 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
-  Register context = ToRegister(instr->context());
   Register result = ToRegister(instr->result());
   __ lw(result, ContextOperand(cp, Context::GLOBAL_INDEX));
 }
@@ -2839,7 +2842,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 A1State a1_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;
 
@@ -2847,7 +2851,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
   RecordPosition(pointers->position());
 
   if (can_invoke_directly) {
-    __ LoadHeapObject(a1, function);
+    if (a1_state == A1_UNINITIALIZED) {
+      __ LoadHeapObject(a1, function);
+    }
+
     // Change context if needed.
     bool change_context =
         (info()->closure()->context() != function->context()) ||
@@ -2884,7 +2891,11 @@ 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);
+  CallKnownFunction(instr->function(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_METHOD,
+                    A1_UNINITIALIZED);
 }
 
 
@@ -3210,7 +3221,7 @@ void LCodeGen::DoRandom(LRandom* instr) {
   // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
   __ And(a3, a1, Operand(0xFFFF));
   __ li(t0, Operand(18273));
-  __ mul(a3, a3, t0);
+  __ Mul(a3, a3, t0);
   __ srl(a1, a1, 16);
   __ Addu(a1, a3, a1);
   // Save state[0].
@@ -3219,7 +3230,7 @@ void LCodeGen::DoRandom(LRandom* instr) {
   // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
   __ And(a3, a0, Operand(0xFFFF));
   __ li(t0, Operand(36969));
-  __ mul(a3, a3, t0);
+  __ Mul(a3, a3, t0);
   __ srl(a0, a0, 16),
   __ Addu(a0, a3, a0);
   // Save state[1].
@@ -3320,13 +3331,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
   ASSERT(ToRegister(instr->function()).is(a1));
   ASSERT(instr->HasPointerMap());
-  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));
+
+  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);
+  }
 }
 
 
@@ -3381,7 +3400,11 @@ 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);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    A1_UNINITIALIZED);
 }
 
 
@@ -3537,14 +3560,16 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
             Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
   }
 
-  Label is_nan;
-  // Check for NaN. All NaNs must be canonicalized.
-  __ BranchF(NULL, &is_nan, eq, value, value);
-  __ Branch(&not_nan);
+  if (instr->NeedsCanonicalization()) {
+    Label is_nan;
+    // Check for NaN. All NaNs must be canonicalized.
+    __ BranchF(NULL, &is_nan, eq, value, value);
+    __ Branch(&not_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(&not_nan);
   __ sdc1(value, MemOperand(scratch));
@@ -4124,7 +4149,6 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
   Register scratch1 = scratch0();
   Register scratch2 = ToRegister(instr->TempAt(0));
   DoubleRegister double_input = ToDoubleRegister(instr->InputAt(0));
-  DoubleRegister double_scratch = double_scratch0();
   FPURegister single_scratch = double_scratch0().low();
 
   if (instr->truncating()) {
@@ -4237,14 +4261,21 @@ void LCodeGen::DoCheckMapCommon(Register reg,
 }
 
 
-void LCodeGen::DoCheckMap(LCheckMap* instr) {
+void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
   Register scratch = scratch0();
   LOperand* input = instr->InputAt(0);
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  Handle<Map> map = instr->hydrogen()->map();
-  DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
-                   instr->environment());
+  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);
 }
 
 
@@ -4360,6 +4391,14 @@ 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);
@@ -4378,14 +4417,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
@@ -4393,9 +4432,9 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
   __ mov(result, zero_reg);
 
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
-  __ LoadHeapObject(a0, constructor);
+  __ li(a0, Operand(Smi::FromInt(instance_size)));
   __ push(a0);
-  CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr);
+  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
   __ StoreToSafepointRegisterSlot(v0, result);
 }
 
@@ -4531,9 +4570,10 @@ 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 = JSObject::GetElement(object, i);
+        Handle<Object> value(fast_elements->get(i));
         if (value->IsJSObject()) {
           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
           __ Addu(a2, result, Operand(*offset));
@@ -4557,6 +4597,23 @@ 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.
@@ -4892,7 +4949,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   Register strict = scratch0();
   __ li(strict, Operand(Smi::FromInt(strict_mode_flag())));
   __ Push(object, key, strict);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -4905,7 +4962,7 @@ void LCodeGen::DoIn(LIn* instr) {
   Register obj = ToRegister(instr->object());
   Register key = ToRegister(instr->key());
   __ Push(key, obj);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
index b508256..94bb945 100644 (file)
@@ -212,12 +212,18 @@ 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);
+                         CallKind call_kind,
+                         A1State a1_state);
 
   void LoadHeapObject(Register result, Handle<HeapObject> object);
 
index 41b060d..4a5fbe3 100644 (file)
@@ -33,8 +33,6 @@
 namespace v8 {
 namespace internal {
 
-static const Register kSavedValueRegister = kLithiumScratchReg;
-
 LGapResolver::LGapResolver(LCodeGen* owner)
     : cgen_(owner),
       moves_(32),
@@ -170,9 +168,9 @@ void LGapResolver::BreakCycle(int index) {
   LOperand* source = moves_[index].source();
   saved_destination_ = moves_[index].destination();
   if (source->IsRegister()) {
-    __ mov(kSavedValueRegister, cgen_->ToRegister(source));
+    __ mov(kLithiumScratchReg, cgen_->ToRegister(source));
   } else if (source->IsStackSlot()) {
-    __ lw(kSavedValueRegister, cgen_->ToMemOperand(source));
+    __ lw(kLithiumScratchReg, cgen_->ToMemOperand(source));
   } else if (source->IsDoubleRegister()) {
     __ mov_d(kLithiumScratchDouble, cgen_->ToDoubleRegister(source));
   } else if (source->IsDoubleStackSlot()) {
@@ -189,11 +187,11 @@ void LGapResolver::RestoreValue() {
   ASSERT(in_cycle_);
   ASSERT(saved_destination_ != NULL);
 
-  // Spilled value is in kSavedValueRegister or kLithiumScratchDouble.
+  // Spilled value is in kLithiumScratchReg or kLithiumScratchDouble.
   if (saved_destination_->IsRegister()) {
-    __ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
+    __ mov(cgen_->ToRegister(saved_destination_), kLithiumScratchReg);
   } else if (saved_destination_->IsStackSlot()) {
-    __ sw(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
+    __ sw(kLithiumScratchReg, cgen_->ToMemOperand(saved_destination_));
   } else if (saved_destination_->IsDoubleRegister()) {
     __ mov_d(cgen_->ToDoubleRegister(saved_destination_),
             kLithiumScratchDouble);
@@ -245,8 +243,8 @@ void LGapResolver::EmitMove(int index) {
           __ sw(at, destination_operand);
         }
       } else {
-        __ lw(kSavedValueRegister, source_operand);
-        __ sw(kSavedValueRegister, destination_operand);
+        __ lw(kLithiumScratchReg, source_operand);
+        __ sw(kLithiumScratchReg, destination_operand);
       }
     }
 
@@ -263,13 +261,13 @@ void LGapResolver::EmitMove(int index) {
       ASSERT(destination->IsStackSlot());
       ASSERT(!in_cycle_);  // Constant moves happen after all cycles are gone.
       if (cgen_->IsInteger32(constant_source)) {
-        __ li(kSavedValueRegister,
+        __ li(kLithiumScratchReg,
               Operand(cgen_->ToInteger32(constant_source)));
       } else {
-        __ LoadObject(kSavedValueRegister,
+        __ LoadObject(kLithiumScratchReg,
                       cgen_->ToHandle(constant_source));
       }
-      __ sw(kSavedValueRegister, cgen_->ToMemOperand(destination));
+      __ sw(kLithiumScratchReg, cgen_->ToMemOperand(destination));
     }
 
   } else if (source->IsDoubleRegister()) {
@@ -291,15 +289,15 @@ void LGapResolver::EmitMove(int index) {
       MemOperand destination_operand = cgen_->ToMemOperand(destination);
       if (in_cycle_) {
         // kLithiumScratchDouble was used to break the cycle,
-        // but kSavedValueRegister is free.
+        // but kLithiumScratchReg is free.
         MemOperand source_high_operand =
             cgen_->ToHighMemOperand(source);
         MemOperand destination_high_operand =
             cgen_->ToHighMemOperand(destination);
-        __ lw(kSavedValueRegister, source_operand);
-        __ sw(kSavedValueRegister, destination_operand);
-        __ lw(kSavedValueRegister, source_high_operand);
-        __ sw(kSavedValueRegister, destination_high_operand);
+        __ lw(kLithiumScratchReg, source_operand);
+        __ sw(kLithiumScratchReg, destination_operand);
+        __ lw(kLithiumScratchReg, source_high_operand);
+        __ sw(kLithiumScratchReg, destination_high_operand);
       } else {
         __ ldc1(kLithiumScratchDouble, source_operand);
         __ sdc1(kLithiumScratchDouble, destination_operand);
index 1e0c216..1eb3ab7 100644 (file)
@@ -108,22 +108,17 @@ void LInstruction::PrintTo(StringStream* stream) {
 }
 
 
-template<int R, int I, int T>
-void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
+void LInstruction::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  for (int i = 0; i < inputs_.length(); i++) {
+  for (int i = 0; i < InputCount(); i++) {
     if (i > 0) stream->Add(" ");
-    inputs_[i]->PrintTo(stream);
+    InputAt(i)->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);
-  }
+void LInstruction::PrintOutputOperandTo(StringStream* stream) {
+  if (HasResult()) result()->PrintTo(stream);
 }
 
 
@@ -732,22 +727,6 @@ 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) {
@@ -760,8 +739,10 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
   if (hinstr->HasObservableSideEffects()) {
     ASSERT(hinstr->next()->IsSimulate());
     HSimulate* sim = HSimulate::cast(hinstr->next());
-    instr = SetInstructionPendingDeoptimizationEnvironment(
-        instr, sim->ast_id());
+    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();
   }
 
   // If instruction does not have side-effects lazy deoptimization
@@ -779,12 +760,6 @@ 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_));
@@ -1296,6 +1271,7 @@ 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));
 }
@@ -1320,6 +1296,12 @@ 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());
@@ -1460,7 +1442,6 @@ LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
 
 
 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
-  Representation r = instr->GetInputRepresentation();
   ASSERT(instr->left()->representation().IsTagged());
   ASSERT(instr->right()->representation().IsTagged());
   LOperand* left = UseFixed(instr->left(), a1);
@@ -1755,9 +1736,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
+LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  LInstruction* result = new(zone()) LCheckMap(value);
+  LInstruction* result = new(zone()) LCheckMaps(value);
   return AssignEnvironment(result);
 }
 
@@ -2248,9 +2229,12 @@ 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_->
-        set_deoptimization_environment(result->environment());
-    ClearInstructionPendingDeoptimizationEnvironment();
+        SetDeferredLazyDeoptimizationEnvironment(result->environment());
+    instruction_pending_deoptimization_environment_ = NULL;
+    pending_deoptimization_ast_id_ = AstNode::kNoNumber;
     return result;
   }
 
@@ -2277,6 +2261,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
                                                undefined,
                                                instr->call_kind(),
                                                instr->is_construct());
+  if (instr->arguments_var() != NULL) {
+    inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
+  }
   current_block_->UpdateEnvironment(inner);
   chunk_->AddInlinedClosure(instr->closure());
   return NULL;
@@ -2284,10 +2271,21 @@ 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 NULL;
+
+  return pop;
 }
 
 
index 5a7bf4d..a04b429 100644 (file)
@@ -71,7 +71,7 @@ class LCodeGen;
   V(CallStub)                                   \
   V(CheckFunction)                              \
   V(CheckInstanceType)                          \
-  V(CheckMap                                  \
+  V(CheckMaps)                                  \
   V(CheckNonSmi)                                \
   V(CheckPrototypeMaps)                         \
   V(CheckSmi)                                   \
@@ -179,7 +179,8 @@ class LCodeGen;
   V(CheckMapValue)                              \
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
-  V(WrapReceiver)
+  V(WrapReceiver)                               \
+  V(Drop)
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
   virtual Opcode opcode() const { return LInstruction::k##type; } \
@@ -202,15 +203,14 @@ class LInstruction: public ZoneObject {
   LInstruction()
       :  environment_(NULL),
          hydrogen_value_(NULL),
-         is_call_(false),
-         is_save_doubles_(false) { }
+         is_call_(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) = 0;
-  virtual void PrintOutputOperandTo(StringStream* stream) = 0;
+  virtual void PrintDataTo(StringStream* stream);
+  virtual void PrintOutputOperandTo(StringStream* stream);
 
   enum Opcode {
     // Declare a unique enum value for each instruction.
@@ -245,22 +245,12 @@ class LInstruction: public ZoneObject {
   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
 
-  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;
@@ -281,7 +271,6 @@ class LInstruction: public ZoneObject {
   LEnvironment* environment_;
   SetOncePointer<LPointerMap> pointer_map_;
   HValue* hydrogen_value_;
-  SetOncePointer<LEnvironment> deoptimization_environment_;
   bool is_call_;
   bool is_save_doubles_;
 };
@@ -305,9 +294,6 @@ 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_;
@@ -533,9 +519,8 @@ 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)
 };
 
 
@@ -833,6 +818,15 @@ 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_;
 };
 
 
@@ -1358,6 +1352,19 @@ 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,6 +1447,7 @@ 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(); }
 };
 
 
@@ -1719,6 +1727,8 @@ 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(); }
 };
 
 
@@ -1869,14 +1879,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
 };
 
 
-class LCheckMap: public LTemplateInstruction<0, 1, 0> {
+class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckMap(LOperand* value) {
+  explicit LCheckMaps(LOperand* value) {
     inputs_[0] = value;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
-  DECLARE_HYDROGEN_ACCESSOR(CheckMap)
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
+  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
 };
 
 
@@ -2349,11 +2359,6 @@ 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);
index e93a417..2c2445b 100644 (file)
@@ -5378,7 +5378,7 @@ CodePatcher::CodePatcher(byte* address, int instructions)
     : address_(address),
       instructions_(instructions),
       size_(instructions * Assembler::kInstrSize),
-      masm_(Isolate::Current(), address, size_ + Assembler::kGap) {
+      masm_(NULL, address, size_ + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
index ae4da93..c48bcc4 100644 (file)
@@ -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,24 +452,26 @@ 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));
-  BranchOrBacktrack(on_equal, eq, a0, Operand(c));
+  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
+  BranchOrBacktrack(on_equal, eq, a0, rhs);
 }
 
 
 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));
-  BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
+  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
+  BranchOrBacktrack(on_not_equal, ne, a0, rhs);
 }
 
 
@@ -478,12 +480,51 @@ void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd(
     uc16 minus,
     uc16 mask,
     Label* on_not_equal) {
-  UNIMPLEMENTED_MIPS();
+  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));
 }
 
 
 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) {
@@ -848,23 +889,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()));
 }
@@ -877,9 +918,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) {
@@ -930,7 +971,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();
@@ -977,7 +1018,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 {
@@ -1134,7 +1175,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(),
@@ -1162,8 +1203,10 @@ 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);
 }
 
@@ -1234,7 +1277,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()));
index d42d4cf..d167f62 100644 (file)
@@ -81,6 +81,14 @@ 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);
index 294bc0a..18a5f5f 100644 (file)
@@ -429,8 +429,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
   // a0 : value.
   Label exit;
   // Check that the map of the object hasn't changed.
+  CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
+                                             : REQUIRE_EXACT_MAP;
   __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label,
-              DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+              DO_SMI_CHECK, mode);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -563,6 +565,8 @@ 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);
 }
 
 
@@ -577,7 +581,7 @@ static void CompileCallLoadPropertyWithInterceptor(
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
           masm->isolate());
-  __ PrepareCEntryArgs(5);
+  __ PrepareCEntryArgs(6);
   __ PrepareCEntryFunction(ref);
 
   CEntryStub stub(1);
@@ -585,10 +589,10 @@ static void CompileCallLoadPropertyWithInterceptor(
 }
 
 
-static const int kFastApiCallArguments = 3;
+static const int kFastApiCallArguments = 4;
 
 
-// Reserves space for the extra arguments to FastHandleApiCall in the
+// Reserves space for the extra arguments to API function in the
 // caller's frame.
 //
 // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
@@ -614,7 +618,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   //  -- sp[0]              : holder (set by CheckPrototypes)
   //  -- sp[4]              : callee JS function
   //  -- sp[8]              : call data
-  //  -- sp[12]             : last JS argument
+  //  -- sp[12]             : isolate
+  //  -- sp[16]             : last JS argument
   //  -- ...
   //  -- sp[(argc + 3) * 4] : first JS argument
   //  -- sp[(argc + 4) * 4] : receiver
@@ -624,7 +629,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   __ LoadHeapObject(t1, function);
   __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
 
-  // Pass the additional arguments FastHandleApiCall expects.
+  // Pass the additional arguments.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
@@ -634,14 +639,17 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
     __ li(t2, call_data);
   }
 
-  // Store JS function and call data.
+  __ li(t3, Operand(ExternalReference::isolate_address()));
+  // Store JS function, call data and isolate.
   __ sw(t1, MemOperand(sp, 1 * kPointerSize));
   __ sw(t2, MemOperand(sp, 2 * kPointerSize));
+  __ sw(t3, MemOperand(sp, 3 * kPointerSize));
 
-  // a2 points to call data as expected by Arguments
-  // (refer to layout above).
-  __ Addu(a2, sp, Operand(2 * kPointerSize));
+  // Prepare arguments.
+  __ Addu(a2, sp, Operand(3 * 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);
@@ -656,9 +664,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 = data
+  // v8::Arguments::implicit_args_
   __ sw(a2, MemOperand(a1, 0 * kPointerSize));
-  // v8::Arguments::values = last argument
+  // v8::Arguments::values_
   __ Addu(t0, a2, Operand(argc * kPointerSize));
   __ sw(t0, MemOperand(a1, 1 * kPointerSize));
   // v8::Arguments::length_ = argc
@@ -836,7 +844,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
           ExternalReference(
               IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
               masm->isolate()),
-          5);
+          6);
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1168,9 +1176,8 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
   __ JumpIfSmi(receiver, miss, scratch1);
 
   // Check that the maps haven't changed.
-  Register reg =
-      CheckPrototypes(object, receiver, holder,
-                      scratch1, scratch2, scratch3, name, miss);
+  CheckPrototypes(object, receiver, holder,
+                  scratch1, scratch2, scratch3, name, miss);
 
   // Return the constant value.
   __ LoadHeapObject(v0, value);
@@ -1205,7 +1212,13 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
   } else {
     __ li(scratch3, Handle<Object>(callback->data()));
   }
-  __ Push(reg, scratch3, name_reg);
+  __ 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));
+
   __ mov(a2, scratch2);  // Saved in case scratch2 == a1.
   __ mov(a1, sp);  // a1 (first argument - see note below) = Handle<String>
 
@@ -1224,7 +1237,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
   // a2 (second argument - see note above) = AccessorInfo&
   __ Addu(a2, sp, kPointerSize);
 
-  const int kStackUnwindSpace = 4;
+  const int kStackUnwindSpace = 5;
   Address getter_address = v8::ToCData<Address>(callback->getter());
   ApiFunction fun(getter_address);
   ExternalReference ref =
@@ -1274,12 +1287,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
                                           name, miss);
     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
 
+    // Preserve the receiver register explicitly whenever it is different from
+    // the holder and it is needed should the interceptor return without any
+    // result. The CALLBACKS case needs the receiver to be passed into C++ code,
+    // the FIELD case might cause a miss during the prototype check.
+    bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
+    bool must_preserve_receiver_reg = !receiver.is(holder_reg) &&
+        (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+
     // Save necessary data before invoking an interceptor.
     // Requires a frame to make GC aware of pushed pointers.
     {
       FrameScope frame_scope(masm(), StackFrame::INTERNAL);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-        // CALLBACKS case needs a receiver to be passed into C++ callback.
+      if (must_preserve_receiver_reg) {
         __ Push(receiver, holder_reg, name_reg);
       } else {
         __ Push(holder_reg, name_reg);
@@ -1303,14 +1323,14 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       __ bind(&interceptor_failed);
       __ pop(name_reg);
       __ pop(holder_reg);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      if (must_preserve_receiver_reg) {
         __ pop(receiver);
       }
       // Leave the internal frame.
     }
     // Check that the maps from interceptor's holder to lookup's holder
     // haven't changed.  And load lookup's holder into |holder| register.
-    if (*interceptor_holder != lookup->holder()) {
+    if (must_perfrom_prototype_check) {
       holder_reg = CheckPrototypes(interceptor_holder,
                                    holder_reg,
                                    Handle<JSObject>(lookup->holder()),
@@ -1340,24 +1360,17 @@ 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);
-      // 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);
-      }
+
+      __ Push(receiver, holder_reg);
+      __ lw(scratch3,
+            FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
+      __ li(scratch1, Operand(ExternalReference::isolate_address()));
+      __ Push(scratch3, scratch1, scratch2, name_reg);
 
       ExternalReference ref =
           ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
                             masm()->isolate());
-      __ TailCallExternalReference(ref, 5, 1);
+      __ TailCallExternalReference(ref, 6, 1);
     }
   } else {  // !compile_followup_inline
     // Call the runtime system to load the interceptor.
@@ -1370,7 +1383,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate());
-    __ TailCallExternalReference(ref, 5, 1);
+    __ TailCallExternalReference(ref, 6, 1);
   }
 }
 
@@ -1737,14 +1750,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, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag));
+  __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize));
   __ Branch(&call_builtin, eq, v0, Operand(t2));
 
   // Set the array's length.
   __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
 
   // Fill with the hole.
-  __ sw(t2, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag));
+  __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize));
   __ Drop(argc + 1);
   __ Ret();
 
@@ -3371,6 +3384,45 @@ 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) {
@@ -3387,8 +3439,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.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
 
   __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
   // a3: elements array
@@ -3496,7 +3548,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
       CpuFeatures::Scope scope(FPU);
       __ mtc1(value, f0);
       __ cvt_d_w(f0, f0);
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag));
+      __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
       __ Ret();
     } else {
       Register dst1 = t2;
@@ -3544,7 +3596,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
 
       __ Cvt_d_uw(f0, value, f22);
 
-      __ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag));
+      __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
 
       __ Ret();
     } else {
@@ -3598,7 +3650,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, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag));
+      __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
       __ Ret();
     } else {
       // Allocate a HeapNumber for the result. Don't use a0 and a1 as
@@ -3726,8 +3778,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.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
 
   __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
 
@@ -4106,9 +4158,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.
-  __ JumpIfNotSmi(a0, &miss_force_generic, at, USE_DELAY_SLOT);
-  // The delay slot can be safely used here, a1 is an object pointer.
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic);
 
   // Get the elements array.
   __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
@@ -4158,8 +4209,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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // 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);
 
   // Get the elements array.
   __ lw(elements_reg,
@@ -4228,13 +4279,12 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
   Register elements_reg = a3;
   Register length_reg = t1;
   Register scratch2 = t2;
-  Register scratch3 = t3;
 
   // 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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // 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);
 
   if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
     __ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4400,7 +4450,9 @@ 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.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  // 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);
 
   __ lw(elements_reg,
          FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
@@ -4492,6 +4544,8 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
     // Increment the length of the array.
     __ li(length_reg, Operand(Smi::FromInt(1)));
     __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
+    __ lw(elements_reg,
+          FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
index c43dd22..c7f0dcc 100644 (file)
@@ -596,6 +596,23 @@ 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_);
@@ -896,6 +913,22 @@ 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();
 };
@@ -1572,7 +1605,7 @@ FrameMirror.prototype.scopeCount = function() {
 
 
 FrameMirror.prototype.scope = function(index) {
-  return new ScopeMirror(this, index);
+  return new ScopeMirror(this, void 0, index);
 };
 
 
@@ -1735,39 +1768,54 @@ FrameMirror.prototype.toText = function(opt_locals) {
 var kScopeDetailsTypeIndex = 0;
 var kScopeDetailsObjectIndex = 1;
 
-function ScopeDetails(frame, index) {
-  this.break_id_ = frame.break_id_;
-  this.details_ = %GetScopeDetails(frame.break_id_,
-                                   frame.details_.frameId(),
-                                   frame.details_.inlinedFrameIndex(),
-                                   index);
+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;
+  }
 }
 
 
 ScopeDetails.prototype.type = function() {
-  %CheckExecutionState(this.break_id_);
+  if (!IS_UNDEFINED(this.break_id_)) {
+    %CheckExecutionState(this.break_id_);
+  }
   return this.details_[kScopeDetailsTypeIndex];
 };
 
 
 ScopeDetails.prototype.object = function() {
-  %CheckExecutionState(this.break_id_);
+  if (!IS_UNDEFINED(this.break_id_)) {
+    %CheckExecutionState(this.break_id_);
+  }
   return this.details_[kScopeDetailsObjectIndex];
 };
 
 
 /**
- * Mirror object for scope.
+ * Mirror object for scope of frame or function. Either frame or function must
+ * be specified.
  * @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, index) {
+function ScopeMirror(frame, function, index) {
   %_CallFunction(this, SCOPE_TYPE, Mirror);
-  this.frame_index_ = frame.index_;
+  if (frame) {
+    this.frame_index_ = frame.index_;
+  } else {
+    this.frame_index_ = undefined;
+  }
   this.scope_index_ = index;
-  this.details_ = new ScopeDetails(frame, index);
+  this.details_ = new ScopeDetails(frame, function, index);
 }
 inherits(ScopeMirror, Mirror);
 
@@ -2234,6 +2282,11 @@ 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;
@@ -2259,6 +2312,15 @@ 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.
index 8eefb23..3bfb74d 100644 (file)
@@ -135,6 +135,9 @@ 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;
@@ -300,6 +303,8 @@ void Map::MapVerify() {
           instance_size() < HEAP->Capacity()));
   VerifyHeapPointer(prototype());
   VerifyHeapPointer(instance_descriptors());
+  SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
+  SLOW_ASSERT(instance_descriptors()->IsConsistentWithBackPointers(this));
 }
 
 
@@ -366,6 +371,15 @@ 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()) {
@@ -882,6 +896,61 @@ bool DescriptorArray::IsSortedNoDuplicates() {
 }
 
 
+static bool CheckOneBackPointer(Map* current_map, Object* target) {
+  return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
+}
+
+
+bool DescriptorArray::IsConsistentWithBackPointers(Map* current_map) {
+  for (int i = 0; i < number_of_descriptors(); ++i) {
+    switch (GetType(i)) {
+      case MAP_TRANSITION:
+      case CONSTANT_TRANSITION:
+        if (!CheckOneBackPointer(current_map, GetValue(i))) {
+          return false;
+        }
+        break;
+      case ELEMENTS_TRANSITION: {
+        Object* object = GetValue(i);
+        if (!CheckOneBackPointer(current_map, object)) {
+          return false;
+        }
+        if (object->IsFixedArray()) {
+          FixedArray* array = FixedArray::cast(object);
+          for (int i = 0; i < array->length(); ++i) {
+            if (!CheckOneBackPointer(current_map, array->get(i))) {
+              return false;
+            }
+          }
+        }
+        break;
+      }
+      case CALLBACKS: {
+        Object* object = GetValue(i);
+        if (object->IsAccessorPair()) {
+          AccessorPair* accessors = AccessorPair::cast(object);
+          if (!CheckOneBackPointer(current_map, accessors->getter())) {
+            return false;
+          }
+          if (!CheckOneBackPointer(current_map, accessors->setter())) {
+            return false;
+          }
+        }
+        break;
+      }
+      case NORMAL:
+      case FIELD:
+      case CONSTANT_FUNCTION:
+      case HANDLER:
+      case INTERCEPTOR:
+      case NULL_DESCRIPTOR:
+        break;
+    }
+  }
+  return true;
+}
+
+
 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
   JSFunction::cast(get(kFactoryIndex))->Verify();
 
index 78578cc..eb1586a 100644 (file)
@@ -581,7 +581,8 @@ 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->block_context_map() ||
+            map == heap->module_context_map());
   }
   return false;
 }
@@ -594,6 +595,13 @@ 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() ==
@@ -613,6 +621,7 @@ 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)
@@ -1383,7 +1392,9 @@ void JSObject::initialize_properties() {
 
 
 void JSObject::initialize_elements() {
-  ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
+  ASSERT(map()->has_fast_elements() ||
+         map()->has_fast_smi_only_elements() ||
+         map()->has_fast_double_elements());
   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
   WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
 }
@@ -1436,6 +1447,8 @@ 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:
@@ -1922,15 +1935,15 @@ Object* DescriptorArray::GetValue(int descriptor_number) {
 }
 
 
-Smi* DescriptorArray::GetDetails(int descriptor_number) {
+PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
   ASSERT(descriptor_number < number_of_descriptors());
-  return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
+  Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
+  return PropertyDetails(Smi::cast(details));
 }
 
 
 PropertyType DescriptorArray::GetType(int descriptor_number) {
-  ASSERT(descriptor_number < number_of_descriptors());
-  return PropertyDetails(GetDetails(descriptor_number)).type();
+  return GetDetails(descriptor_number).type();
 }
 
 
@@ -1993,15 +2006,10 @@ 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),
-             PropertyDetails(GetDetails(descriptor_number)));
+             GetDetails(descriptor_number));
 }
 
 
@@ -3004,26 +3012,26 @@ void Code::set_is_pregenerated(bool value) {
 
 
 bool Code::optimizable() {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
 }
 
 
 void Code::set_optimizable(bool value) {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
 }
 
 
 bool Code::has_deoptimization_support() {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
   return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
 }
 
 
 void Code::set_has_deoptimization_support(bool value) {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
   flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
@@ -3031,14 +3039,14 @@ void Code::set_has_deoptimization_support(bool value) {
 
 
 bool Code::has_debug_break_slots() {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
   return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
 }
 
 
 void Code::set_has_debug_break_slots(bool value) {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
   flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
@@ -3046,45 +3054,43 @@ void Code::set_has_debug_break_slots(bool value) {
 
 
 bool Code::is_compiled_optimizable() {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
   return FullCodeFlagsIsCompiledOptimizable::decode(flags);
 }
 
 
 void Code::set_compiled_optimizable(bool value) {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   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);
+int Code::allow_osr_at_loop_nesting_level() {
+  ASSERT_EQ(FUNCTION, kind());
+  return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
 }
 
 
-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);
+void Code::set_allow_osr_at_loop_nesting_level(int level) {
+  ASSERT_EQ(FUNCTION, kind());
+  ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
+  WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
 }
 
 
-int Code::allow_osr_at_loop_nesting_level() {
-  ASSERT(kind() == FUNCTION);
-  return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
+int Code::profiler_ticks() {
+  ASSERT_EQ(FUNCTION, kind());
+  return READ_BYTE_FIELD(this, kProfilerTicksOffset);
 }
 
 
-void Code::set_allow_osr_at_loop_nesting_level(int level) {
-  ASSERT(kind() == FUNCTION);
-  ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
-  WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
+void Code::set_profiler_ticks(int ticks) {
+  ASSERT_EQ(FUNCTION, kind());
+  ASSERT(ticks < 256);
+  WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
 }
 
 
@@ -3114,13 +3120,13 @@ void Code::set_safepoint_table_offset(unsigned offset) {
 
 
 unsigned Code::stack_check_table_offset() {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
 }
 
 
 void Code::set_stack_check_table_offset(unsigned offset) {
-  ASSERT(kind() == FUNCTION);
+  ASSERT_EQ(FUNCTION, kind());
   ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
   WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
 }
@@ -3187,6 +3193,18 @@ void Code::set_compare_state(byte value) {
 }
 
 
+byte Code::compare_operation() {
+  ASSERT(is_compare_ic_stub());
+  return READ_BYTE_FIELD(this, kCompareOperationOffset);
+}
+
+
+void Code::set_compare_operation(byte value) {
+  ASSERT(is_compare_ic_stub());
+  WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
+}
+
+
 byte Code::to_boolean_state() {
   ASSERT(is_to_boolean_ic_stub());
   return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
@@ -3389,14 +3407,66 @@ void Map::set_bit_field3(int value) {
 }
 
 
-FixedArray* Map::unchecked_prototype_transitions() {
-  return reinterpret_cast<FixedArray*>(
-      READ_FIELD(this, kPrototypeTransitionsOffset));
+Object* Map::GetBackPointer() {
+  Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
+  if (object->IsFixedArray()) {
+    return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
+  } else {
+    return object;
+  }
+}
+
+
+void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
+  Heap* heap = GetHeap();
+  ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
+  ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
+         (value->IsMap() && GetBackPointer()->IsUndefined()));
+  Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
+  if (object->IsFixedArray()) {
+    FixedArray::cast(object)->set(
+        kProtoTransitionBackPointerOffset, value, mode);
+  } else {
+    WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
+    CONDITIONAL_WRITE_BARRIER(
+        heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
+  }
+}
+
+
+FixedArray* Map::prototype_transitions() {
+  Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
+  if (object->IsFixedArray()) {
+    return FixedArray::cast(object);
+  } else {
+    return GetHeap()->empty_fixed_array();
+  }
+}
+
+
+void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
+  Heap* heap = GetHeap();
+  ASSERT(value != heap->empty_fixed_array());
+  value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
+  WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
+  CONDITIONAL_WRITE_BARRIER(
+      heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
+}
+
+
+void Map::init_prototype_transitions(Object* undefined) {
+  ASSERT(undefined->IsUndefined());
+  WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
+}
+
+
+HeapObject* Map::unchecked_prototype_transitions() {
+  Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
+  return reinterpret_cast<HeapObject*>(object);
 }
 
 
 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
-ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
 ACCESSORS(Map, constructor, Object, kConstructorOffset)
 
 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
@@ -3507,8 +3577,8 @@ ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
           kThisPropertyAssignmentsOffset)
+SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
 
-SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
 
 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
                kHiddenPrototypeBit)
@@ -3654,6 +3724,12 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) {
 }
 
 
+int SharedFunctionInfo::profiler_ticks() {
+  if (code()->kind() != Code::FUNCTION) return 0;
+  return code()->profiler_ticks();
+}
+
+
 LanguageMode SharedFunctionInfo::language_mode() {
   int hints = compiler_hints();
   if (BooleanBit::get(hints, kExtendedModeFunction)) {
@@ -4080,6 +4156,16 @@ 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)
 
 
@@ -4814,7 +4900,7 @@ Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
 
 
 SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
-SMI_ACCESSORS(TypeFeedbackInfo, ic_with_typeinfo_count,
+SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
               kIcWithTypeinfoCountOffset)
 ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
           kTypeFeedbackCellsOffset)
index 38e6138..febdaab 100644 (file)
@@ -135,6 +135,9 @@ 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;
@@ -152,7 +155,7 @@ void HeapObject::HeapObjectPrint(FILE* out) {
       JSValue::cast(this)->value()->Print(out);
       break;
     case JS_DATE_TYPE:
-      JSDate::cast(this)->value()->Print(out);
+      JSDate::cast(this)->JSDatePrint(out);
       break;
     case CODE_TYPE:
       Code::cast(this)->CodePrint(out);
@@ -328,14 +331,16 @@ void JSObject::PrintElements(FILE* out) {
     }
     case FAST_DOUBLE_ELEMENTS: {
       // Print in array notation for non-sparse arrays.
-      FixedDoubleArray* p = FixedDoubleArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        if (p->is_the_hole(i)) {
-          PrintF(out, "   %d: <the hole>", i);
-        } else {
-          PrintF(out, "   %d: %g", i, p->get_scalar(i));
+      if (elements()->length() > 0) {
+        FixedDoubleArray* p = FixedDoubleArray::cast(elements());
+        for (int i = 0; i < p->length(); i++) {
+          if (p->is_the_hole(i)) {
+            PrintF(out, "   %d: <the hole>", i);
+          } else {
+            PrintF(out, "   %d: %g", i, p->get_scalar(i));
+          }
+          PrintF(out, "\n");
         }
-        PrintF(out, "\n");
       }
       break;
     }
@@ -437,6 +442,19 @@ 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";
@@ -483,6 +501,7 @@ 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";
@@ -559,8 +578,8 @@ void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) {
 
 void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) {
   HeapObject::PrintHeader(out, "TypeFeedbackInfo");
-  PrintF(out, "\n - ic_total_count: %d, ic_with_typeinfo_count: %d",
-         ic_total_count(), ic_with_typeinfo_count());
+  PrintF(out, "\n - ic_total_count: %d, ic_with_type_info_count: %d",
+         ic_total_count(), ic_with_type_info_count());
   PrintF(out, "\n - type_feedback_cells: ");
   type_feedback_cells()->FixedArrayPrint(out);
 }
index 627d1bc..8ba92f7 100644 (file)
@@ -72,9 +72,7 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
 
   table_.Register(kVisitSeqTwoByteString, &VisitSeqTwoByteString);
 
-  table_.Register(kVisitJSFunction,
-                  &JSObjectVisitor::
-                      template VisitSpecialized<JSFunction::kSize>);
+  table_.Register(kVisitJSFunction, &VisitJSFunction);
 
   table_.Register(kVisitFreeSpace, &VisitFreeSpace);
 
index c7c8a87..a2dc43e 100644 (file)
@@ -133,6 +133,7 @@ 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:
index 26e79ae..b476dfe 100644 (file)
@@ -289,6 +289,23 @@ 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();
   }
index 64d85a0..7f75611 100644 (file)
@@ -1338,6 +1338,7 @@ 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:
@@ -1390,9 +1391,11 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
     case EXTERNAL_FLOAT_ARRAY_TYPE:
     case EXTERNAL_DOUBLE_ARRAY_TYPE:
       break;
-    case SHARED_FUNCTION_INFO_TYPE:
-      SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
+    case SHARED_FUNCTION_INFO_TYPE: {
+      SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);
+      shared->SharedFunctionInfoIterateBody(v);
       break;
+    }
 
 #define MAKE_STRUCT_CASE(NAME, Name, name) \
         case NAME##_TYPE:
@@ -1601,6 +1604,7 @@ MaybeObject* JSObject::AddFastProperty(String* name,
   // We have now allocated all the necessary objects.
   // All the changes can be applied at once, so they are atomic.
   map()->set_instance_descriptors(old_descriptors);
+  new_map->SetBackPointer(map());
   new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
   set_map(new_map);
   return FastPropertyAtPut(index, value);
@@ -1661,6 +1665,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
     }
   }
   old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+  Map::cast(new_map)->SetBackPointer(old_map);
 
   return function;
 }
@@ -1821,6 +1826,7 @@ MaybeObject* JSObject::ConvertDescriptorToFieldAndMapTransition(
     }
   }
   old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+  map()->SetBackPointer(old_map);
   return result;
 }
 
@@ -2319,7 +2325,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 {
@@ -2405,6 +2411,7 @@ MaybeObject* Map::AddElementsTransition(ElementsKind elements_kind,
     return maybe_new_descriptors;
   }
   set_instance_descriptors(DescriptorArray::cast(new_descriptors));
+  transitioned_map->SetBackPointer(this);
   return this;
 }
 
@@ -3023,7 +3030,6 @@ 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;
@@ -3092,7 +3098,6 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     case HANDLER:
       UNREACHABLE();
-      return value;
   }
   UNREACHABLE();  // keep the compiler happy
   return value;
@@ -3343,7 +3348,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 =
@@ -3751,13 +3756,11 @@ MaybeObject* JSObject::GetHiddenPropertiesDictionary(bool create_if_absent) {
   MaybeObject* dict_alloc = StringDictionary::Allocate(kInitialSize);
   StringDictionary* dictionary;
   if (!dict_alloc->To<StringDictionary>(&dictionary)) return dict_alloc;
-  MaybeObject* store_result =
-      SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
-                                 dictionary,
-                                 DONT_ENUM,
-                                 kNonStrictMode);
-  if (store_result->IsFailure()) return store_result;
-  return dictionary;
+  // 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);
 }
 
 
@@ -4207,7 +4210,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++;
     }
@@ -4410,37 +4413,56 @@ MaybeObject* JSObject::DefineElementAccessor(uint32_t index,
 }
 
 
+MaybeObject* JSObject::CreateAccessorPairFor(String* name) {
+  LookupResult result(GetHeap()->isolate());
+  LocalLookupRealNamedProperty(name, &result);
+  if (result.IsProperty() && result.type() == CALLBACKS) {
+    // Note that the result can actually have IsDontDelete() == true when we
+    // e.g. have to fall back to the slow case while adding a setter after
+    // successfully reusing a map transition for a getter. Nevertheless, this is
+    // OK, because the assertion only holds for the whole addition of both
+    // accessors, not for the addition of each part. See first comment in
+    // DefinePropertyAccessor below.
+    Object* obj = result.GetCallbackObject();
+    if (obj->IsAccessorPair()) {
+      return AccessorPair::cast(obj)->CopyWithoutTransitions();
+    }
+  }
+  return GetHeap()->AllocateAccessorPair();
+}
+
+
 MaybeObject* JSObject::DefinePropertyAccessor(String* name,
                                               Object* getter,
                                               Object* setter,
                                               PropertyAttributes attributes) {
-  // Lookup the name.
-  LookupResult result(GetHeap()->isolate());
-  LocalLookupRealNamedProperty(name, &result);
-  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(&copy)) return maybe_copy;
-        }
-        copy->SetComponents(getter, setter);
-        // Use set to update attributes.
-        return SetPropertyCallback(name, copy, attributes);
-      }
+  // We could assert that the property is configurable here, but we would need
+  // to do a lookup, which seems to be a bit of overkill.
+  Heap* heap = GetHeap();
+  bool only_attribute_changes = getter->IsNull() && setter->IsNull();
+  if (HasFastProperties() && !only_attribute_changes) {
+    MaybeObject* getterOk = heap->undefined_value();
+    if (!getter->IsNull()) {
+      getterOk = DefineFastAccessor(name, ACCESSOR_GETTER, getter, attributes);
+      if (getterOk->IsFailure()) return getterOk;
+    }
+
+    MaybeObject* setterOk = heap->undefined_value();
+    if (getterOk != heap->null_value() && !setter->IsNull()) {
+      setterOk = DefineFastAccessor(name, ACCESSOR_SETTER, setter, attributes);
+      if (setterOk->IsFailure()) return setterOk;
+    }
+
+    if (getterOk != heap->null_value() && setterOk != heap->null_value()) {
+      return heap->undefined_value();
     }
   }
 
   AccessorPair* accessors;
-  { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair();
+  { MaybeObject* maybe_accessors = CreateAccessorPairFor(name);
     if (!maybe_accessors->To(&accessors)) return maybe_accessors;
   }
   accessors->SetComponents(getter, setter);
-
   return SetPropertyCallback(name, accessors, attributes);
 }
 
@@ -4585,6 +4607,159 @@ MaybeObject* JSObject::DefineAccessor(String* name,
 }
 
 
+static MaybeObject* CreateFreshAccessor(JSObject* obj,
+                                        String* name,
+                                        AccessorComponent component,
+                                        Object* accessor,
+                                        PropertyAttributes attributes) {
+  // step 1: create a new getter/setter pair with only the accessor in it
+  Heap* heap = obj->GetHeap();
+  AccessorPair* accessors2;
+  { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair();
+    if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2;
+  }
+  accessors2->set(component, accessor);
+
+  // step 2: create a copy of the descriptors, incl. the new getter/setter pair
+  Map* map1 = obj->map();
+  CallbacksDescriptor callbacks_descr2(name, accessors2, attributes);
+  DescriptorArray* descriptors2;
+  { MaybeObject* maybe_descriptors2 =
+        map1->instance_descriptors()->CopyInsert(&callbacks_descr2,
+                                                 REMOVE_TRANSITIONS);
+    if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2;
+  }
+
+  // step 3: create a new map with the new descriptors
+  Map* map2;
+  { MaybeObject* maybe_map2 = map1->CopyDropDescriptors();
+    if (!maybe_map2->To(&map2)) return maybe_map2;
+  }
+  map2->set_instance_descriptors(descriptors2);
+
+  // step 4: create a new getter/setter pair with a transition to the new map
+  AccessorPair* accessors1;
+  { MaybeObject* maybe_accessors1 = heap->AllocateAccessorPair();
+    if (!maybe_accessors1->To(&accessors1)) return maybe_accessors1;
+  }
+  accessors1->set(component, map2);
+
+  // step 5: create a copy of the descriptors, incl. the new getter/setter pair
+  // with the transition
+  CallbacksDescriptor callbacks_descr1(name, accessors1, attributes);
+  DescriptorArray* descriptors1;
+  { MaybeObject* maybe_descriptors1 =
+        map1->instance_descriptors()->CopyInsert(&callbacks_descr1,
+                                                 KEEP_TRANSITIONS);
+    if (!maybe_descriptors1->To(&descriptors1)) return maybe_descriptors1;
+  }
+
+  // step 6: everything went well so far, so we make our changes visible
+  obj->set_map(map2);
+  map1->set_instance_descriptors(descriptors1);
+  map2->SetBackPointer(map1);
+  return obj;
+}
+
+
+static bool TransitionToSameAccessor(Object* map,
+                                     String* name,
+                                     AccessorComponent component,
+                                     Object* accessor,
+                                     PropertyAttributes attributes ) {
+  DescriptorArray* descs = Map::cast(map)->instance_descriptors();
+  int number = descs->SearchWithCache(name);
+  ASSERT(number != DescriptorArray::kNotFound);
+  Object* target_accessor =
+      AccessorPair::cast(descs->GetCallbacksObject(number))->get(component);
+  PropertyAttributes target_attributes = descs->GetDetails(number).attributes();
+  return target_accessor == accessor && target_attributes == attributes;
+}
+
+
+static MaybeObject* NewCallbackTransition(JSObject* obj,
+                                          String* name,
+                                          AccessorComponent component,
+                                          Object* accessor,
+                                          PropertyAttributes attributes,
+                                          AccessorPair* accessors2) {
+  // step 1: copy the old getter/setter pair and set the new accessor
+  AccessorPair* accessors3;
+  { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions();
+    if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3;
+  }
+  accessors3->set(component, accessor);
+
+  // step 2: create a copy of the descriptors, incl. the new getter/setter pair
+  Map* map2 = obj->map();
+  CallbacksDescriptor callbacks_descr3(name, accessors3, attributes);
+  DescriptorArray* descriptors3;
+  { MaybeObject* maybe_descriptors3 =
+        map2->instance_descriptors()->CopyInsert(&callbacks_descr3,
+                                                 REMOVE_TRANSITIONS);
+    if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3;
+  }
+
+  // step 3: create a new map with the new descriptors
+  Map* map3;
+  { MaybeObject* maybe_map3 = map2->CopyDropDescriptors();
+    if (!maybe_map3->To(&map3)) return maybe_map3;
+  }
+  map3->set_instance_descriptors(descriptors3);
+
+  // step 4: everything went well so far, so we make our changes visible
+  obj->set_map(map3);
+  accessors2->set(component, map3);
+  map3->SetBackPointer(map2);
+  return obj;
+}
+
+
+MaybeObject* JSObject::DefineFastAccessor(String* name,
+                                          AccessorComponent component,
+                                          Object* accessor,
+                                          PropertyAttributes attributes) {
+  ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
+  LookupResult result(GetIsolate());
+  LocalLookup(name, &result);
+
+  // If we have a new property, create a fresh accessor plus a transition to it.
+  if (!result.IsFound()) {
+    return CreateFreshAccessor(this, name, component, accessor, attributes);
+  }
+
+  // If the property is not a JavaScript accessor, fall back to the slow case.
+  if (result.type() != CALLBACKS) return GetHeap()->null_value();
+  Object* callback_value = result.GetValue();
+  if (!callback_value->IsAccessorPair()) return GetHeap()->null_value();
+  AccessorPair* accessors = AccessorPair::cast(callback_value);
+
+  // Follow a callback transition, if there is a fitting one.
+  Object* entry = accessors->get(component);
+  if (entry->IsMap() &&
+      TransitionToSameAccessor(entry, name, component, accessor, attributes)) {
+    set_map(Map::cast(entry));
+    return this;
+  }
+
+  // When we re-add the same accessor again, there is nothing to do.
+  if (entry == accessor && result.GetAttributes() == attributes) return this;
+
+  // Only the other accessor has been set so far, create a new transition.
+  if (entry->IsTheHole()) {
+    return NewCallbackTransition(this,
+                                 name,
+                                 component,
+                                 accessor,
+                                 attributes,
+                                 accessors);
+  }
+
+  // Nothing from the above worked, so we have to fall back to the slow case.
+  return GetHeap()->null_value();
+}
+
+
 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
   Isolate* isolate = GetIsolate();
   String* name = String::cast(info->name());
@@ -4968,7 +5143,7 @@ class IntrusiveMapTransitionIterator {
 // underlying array while it is running.
 class IntrusivePrototypeTransitionIterator {
  public:
-  explicit IntrusivePrototypeTransitionIterator(FixedArray* proto_trans)
+  explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans)
       : proto_trans_(proto_trans) { }
 
   void Start() {
@@ -4993,7 +5168,7 @@ class IntrusivePrototypeTransitionIterator {
 
  private:
   bool HasTransitions() {
-    return proto_trans_->length() >= Map::kProtoTransitionHeaderSize;
+    return proto_trans_->map()->IsSmi() || proto_trans_->IsFixedArray();
   }
 
   Object** Header() {
@@ -5001,12 +5176,16 @@ class IntrusivePrototypeTransitionIterator {
   }
 
   int NumberOfTransitions() {
-    Object* num = proto_trans_->get(Map::kProtoTransitionNumberOfEntriesOffset);
+    ASSERT(HasTransitions());
+    FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
+    Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset);
     return Smi::cast(num)->value();
   }
 
   Map* GetTransition(int transitionNumber) {
-    return Map::cast(proto_trans_->get(IndexFor(transitionNumber)));
+    ASSERT(HasTransitions());
+    FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_);
+    return Map::cast(proto_trans->get(IndexFor(transitionNumber)));
   }
 
   int IndexFor(int transitionNumber) {
@@ -5015,7 +5194,7 @@ class IntrusivePrototypeTransitionIterator {
         transitionNumber * Map::kProtoTransitionElementsPerEntry;
   }
 
-  FixedArray* proto_trans_;
+  HeapObject* proto_trans_;
 };
 
 
@@ -5696,7 +5875,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();
@@ -5739,7 +5918,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 = PropertyDetails(GetDetails(index)).type();
+    PropertyType t = GetDetails(index).type();
     if (t == CONSTANT_FUNCTION ||
         t == FIELD ||
         t == CALLBACKS ||
@@ -5766,8 +5945,7 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor,
   int enumeration_index = NextEnumerationIndex();
   if (!descriptor->ContainsTransition()) {
     if (keep_enumeration_index) {
-      descriptor->SetEnumerationIndex(
-          PropertyDetails(GetDetails(index)).index());
+      descriptor->SetEnumerationIndex(GetDetails(index).index());
     } else {
       descriptor->SetEnumerationIndex(enumeration_index);
       ++enumeration_index;
@@ -5911,10 +6089,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  && !is_null_descriptor(mid)) return mid;
+    if (name == mid_name  && !IsNullDescriptor(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) && !is_null_descriptor(mid)) return mid;
+      if (GetKey(mid)->Equals(name) && !IsNullDescriptor(mid)) return mid;
     }
     break;
   }
@@ -5928,7 +6106,7 @@ int DescriptorArray::LinearSearch(String* name, int len) {
     String* entry = GetKey(number);
     if ((entry->Hash() == hash) &&
         name->Equals(entry) &&
-        !is_null_descriptor(number)) {
+        !IsNullDescriptor(number)) {
       return number;
     }
   }
@@ -5949,8 +6127,8 @@ MaybeObject* AccessorPair::CopyWithoutTransitions() {
 
 
 Object* AccessorPair::GetComponent(AccessorComponent component) {
-    Object* accessor = (component == ACCESSOR_GETTER) ? getter() : setter();
-    return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
+  Object* accessor = get(component);
+  return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
 }
 
 
@@ -7178,85 +7356,23 @@ void String::PrintOn(FILE* file) {
 }
 
 
-void Map::CreateOneBackPointer(Object* transition_target) {
-  if (!transition_target->IsMap()) return;
-  Map* target = Map::cast(transition_target);
-#ifdef DEBUG
-  // Verify target.
-  Object* source_prototype = prototype();
-  Object* target_prototype = target->prototype();
-  ASSERT(source_prototype->IsJSReceiver() ||
-         source_prototype->IsMap() ||
-         source_prototype->IsNull());
-  ASSERT(target_prototype->IsJSReceiver() ||
-         target_prototype->IsNull());
-  ASSERT(source_prototype->IsMap() ||
-         source_prototype == target_prototype);
-#endif
-  // Point target back to source.  set_prototype() will not let us set
-  // the prototype to a map, as we do here.
-  *RawField(target, kPrototypeOffset) = this;
-}
-
-
-void Map::CreateBackPointers() {
-  DescriptorArray* descriptors = instance_descriptors();
-  for (int i = 0; i < descriptors->number_of_descriptors(); i++) {
-    switch (descriptors->GetType(i)) {
-      case MAP_TRANSITION:
-      case CONSTANT_TRANSITION:
-        CreateOneBackPointer(descriptors->GetValue(i));
-        break;
-      case ELEMENTS_TRANSITION: {
-        Object* object = descriptors->GetValue(i);
-        if (object->IsMap()) {
-          CreateOneBackPointer(object);
-        } else {
-          FixedArray* array = FixedArray::cast(object);
-          for (int i = 0; i < array->length(); ++i) {
-            CreateOneBackPointer(array->get(i));
-          }
-        }
-        break;
-      }
-      case CALLBACKS: {
-        Object* object = descriptors->GetValue(i);
-        if (object->IsAccessorPair()) {
-          AccessorPair* accessors = AccessorPair::cast(object);
-          CreateOneBackPointer(accessors->getter());
-          CreateOneBackPointer(accessors->setter());
-        }
-        break;
-      }
-      case NORMAL:
-      case FIELD:
-      case CONSTANT_FUNCTION:
-      case HANDLER:
-      case INTERCEPTOR:
-      case NULL_DESCRIPTOR:
-        break;
-    }
-  }
-}
-
-
-bool Map::RestoreOneBackPointer(Object* object,
-                                Object* real_prototype,
-                                bool* keep_entry) {
-  if (!object->IsMap()) return false;
-  Map* map = Map::cast(object);
+// Clear a possible back pointer in case the transition leads to a dead map.
+// Return true in case a back pointer has been cleared and false otherwise.
+// Set *keep_entry to true when a live map transition has been found.
+static bool ClearBackPointer(Heap* heap, Object* target, bool* keep_entry) {
+  if (!target->IsMap()) return false;
+  Map* map = Map::cast(target);
   if (Marking::MarkBitFrom(map).Get()) {
     *keep_entry = true;
     return false;
+  } else {
+    map->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
+    return true;
   }
-  ASSERT(map->prototype() == this || map->prototype() == real_prototype);
-  // Getter prototype() is read-only, set_prototype() has side effects.
-  *RawField(map, Map::kPrototypeOffset) = real_prototype;
-  return true;
 }
 
 
-void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) {
+void Map::ClearNonLiveTransitions(Heap* heap) {
   DescriptorArray* d = DescriptorArray::cast(
       *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset));
   if (d->IsEmpty()) return;
@@ -7269,24 +7385,22 @@ void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) {
     // If the pair (value, details) is a map transition, check if the target is
     // live. If not, null the descriptor. Also drop the back pointer for that
     // map transition, so that this map is not reached again by following a back
-    // pointer from a non-live object.
+    // pointer from that non-live map.
     bool keep_entry = false;
     PropertyDetails details(Smi::cast(contents->get(i + 1)));
     switch (details.type()) {
       case MAP_TRANSITION:
       case CONSTANT_TRANSITION:
-        RestoreOneBackPointer(contents->get(i), real_prototype, &keep_entry);
+        ClearBackPointer(heap, contents->get(i), &keep_entry);
         break;
       case ELEMENTS_TRANSITION: {
         Object* object = contents->get(i);
         if (object->IsMap()) {
-          RestoreOneBackPointer(object, real_prototype, &keep_entry);
+          ClearBackPointer(heap, object, &keep_entry);
         } else {
           FixedArray* array = FixedArray::cast(object);
           for (int j = 0; j < array->length(); ++j) {
-            if (RestoreOneBackPointer(array->get(j),
-                                      real_prototype,
-                                      &keep_entry)) {
+            if (ClearBackPointer(heap, array->get(j), &keep_entry)) {
               array->set_undefined(j);
             }
           }
@@ -7297,14 +7411,10 @@ void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) {
         Object* object = contents->get(i);
         if (object->IsAccessorPair()) {
           AccessorPair* accessors = AccessorPair::cast(object);
-          if (RestoreOneBackPointer(accessors->getter(),
-                                    real_prototype,
-                                    &keep_entry)) {
+          if (ClearBackPointer(heap, accessors->getter(), &keep_entry)) {
             accessors->set_getter(heap->the_hole_value());
           }
-          if (RestoreOneBackPointer(accessors->setter(),
-                                    real_prototype,
-                                    &keep_entry)) {
+          if (ClearBackPointer(heap, accessors->setter(), &keep_entry)) {
             accessors->set_setter(heap->the_hole_value());
           }
         } else {
@@ -7869,6 +7979,22 @@ void SharedFunctionInfo::AttachInitialMap(Map* map) {
 }
 
 
+void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
+  code()->ClearInlineCaches();
+  set_ic_age(new_ic_age);
+  if (code()->kind() == Code::FUNCTION) {
+    code()->set_profiler_ticks(0);
+    if (optimization_disabled() &&
+        opt_count() >= Compiler::kDefaultMaxOptCount) {
+      // Re-enable optimizations if they were disabled due to opt_count limit.
+      set_optimization_disabled(false);
+      code()->set_optimizable(true);
+    }
+    set_opt_count(0);
+  }
+}
+
+
 static void GetMinInobjectSlack(Map* map, void* data) {
   int slack = map->unused_property_fields();
   if (*reinterpret_cast<int*>(data) > slack) {
@@ -7912,6 +8038,12 @@ void SharedFunctionInfo::CompleteInobjectSlackTracking() {
 }
 
 
+void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
+  v->VisitSharedFunctionInfo(this);
+  SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
+}
+
+
 #define DECLARE_TAG(ignore1, name, ignore2) name,
 const char* const VisitorSynchronization::kTags[
     VisitorSynchronization::kNumberOfSyncTags] = {
@@ -7969,7 +8101,6 @@ void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
   CHECK_EQ(target, old_target);  // VisitPointer doesn't change Code* *target.
 }
 
-
 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
   ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
   VisitPointer(rinfo->target_object_address());
@@ -8116,6 +8247,35 @@ Map* Code::FindFirstMap() {
 }
 
 
+void Code::ClearInlineCaches() {
+  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
+             RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
+             RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
+             RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
+  for (RelocIterator it(this, mask); !it.done(); it.next()) {
+    RelocInfo* info = it.rinfo();
+    Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
+    if (target->is_inline_cache_stub()) {
+      IC::Clear(info->pc());
+    }
+  }
+}
+
+
+void Code::ClearTypeFeedbackCells(Heap* heap) {
+  Object* raw_info = type_feedback_info();
+  if (raw_info->IsTypeFeedbackInfo()) {
+    TypeFeedbackCells* type_feedback_cells =
+        TypeFeedbackInfo::cast(raw_info)->type_feedback_cells();
+    for (int i = 0; i < type_feedback_cells->CellCount(); i++) {
+      ASSERT(type_feedback_cells->AstId(i)->IsSmi());
+      JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i);
+      cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap));
+    }
+  }
+}
+
+
 #ifdef ENABLE_DISASSEMBLER
 
 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
@@ -8348,6 +8508,14 @@ 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 (is_compare_ic_stub() && major_key() == CodeStub::CompareIC) {
+      Token::Value op = CompareIC::ComputeOperation(this);
+      PrintF(out, "compare_operation = %s\n", Token::Name(op));
+    }
   }
   if ((name != NULL) && (name[0] != '\0')) {
     PrintF(out, "name = %s\n", name);
@@ -8453,8 +8621,10 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
   ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS)
       ? FAST_SMI_ONLY_ELEMENTS
       : FAST_ELEMENTS;
-  //  int copy_size = Min(old_elements_raw->length(), new_elements->length());
-  accessor->CopyElements(this, new_elements, to_kind);
+  { MaybeObject* maybe_obj =
+        accessor->CopyElements(this, new_elements, to_kind);
+    if (maybe_obj->IsFailure()) return maybe_obj;
+  }
   if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
     set_map_and_elements(new_map, new_elements);
   } else {
@@ -8483,7 +8653,7 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
   // We should never end in here with a pixel or external array.
   ASSERT(!HasExternalArrayElements());
 
-  FixedDoubleArray* elems;
+  FixedArrayBase* elems;
   { MaybeObject* maybe_obj =
         heap->AllocateUninitializedFixedDoubleArray(capacity);
     if (!maybe_obj->To(&elems)) return maybe_obj;
@@ -8498,7 +8668,10 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
   FixedArrayBase* old_elements = elements();
   ElementsKind elements_kind = GetElementsKind();
   ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
-  accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS);
+  { MaybeObject* maybe_obj =
+        accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS);
+    if (maybe_obj->IsFailure()) return maybe_obj;
+  }
   if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
     set_map_and_elements(new_map, elems);
   } else {
@@ -9634,9 +9807,10 @@ MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
   ElementsKind from_kind = map()->elements_kind();
 
   Isolate* isolate = GetIsolate();
-  if (from_kind == FAST_SMI_ONLY_ELEMENTS &&
-      (to_kind == FAST_ELEMENTS ||
-       elements() == isolate->heap()->empty_fixed_array())) {
+  if ((from_kind == FAST_SMI_ONLY_ELEMENTS ||
+      elements() == isolate->heap()->empty_fixed_array()) &&
+      to_kind == FAST_ELEMENTS) {
+    ASSERT(from_kind != FAST_ELEMENTS);
     MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind);
     Map* new_map;
     if (!maybe_new_map->To(&new_map)) return maybe_new_map;
@@ -12814,7 +12988,7 @@ int BreakPointInfo::GetBreakPointCount() {
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
-MaybeObject* JSDate::GetField(Object* object, Smi* index) {
+Object* JSDate::GetField(Object* object, Smi* index) {
   return JSDate::cast(object)->DoGetField(
       static_cast<FieldIndex>(index->value()));
 }
index ced23a9..22993f2 100644 (file)
@@ -59,6 +59,7 @@
 //           - JSWeakMap
 //           - JSRegExp
 //           - JSFunction
+//           - JSModule
 //           - GlobalObject
 //             - JSGlobalObject
 //             - JSBuiltinsObject
@@ -306,6 +307,7 @@ 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)                                                      \
@@ -626,6 +628,7 @@ 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,
@@ -677,6 +680,7 @@ 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);
 
 
@@ -700,12 +704,13 @@ enum CompareResult {
                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
 
 
+class AccessorPair;
 class DictionaryElementsAccessor;
 class ElementsAccessor;
+class Failure;
 class FixedArrayBase;
 class ObjectVisitor;
 class StringStream;
-class Failure;
 
 struct ValueInfo : public Malloced {
   ValueInfo() : type(FIRST_TYPE), ptr(NULL), str(NULL), number(0) { }
@@ -803,6 +808,7 @@ class MaybeObject BASE_EMBEDDED {
   V(JSReceiver)                                \
   V(JSObject)                                  \
   V(JSContextExtensionObject)                  \
+  V(JSModule)                                  \
   V(Map)                                       \
   V(DescriptorArray)                           \
   V(DeoptimizationInputData)                   \
@@ -812,6 +818,7 @@ class MaybeObject BASE_EMBEDDED {
   V(FixedDoubleArray)                          \
   V(Context)                                   \
   V(GlobalContext)                             \
+  V(ModuleContext)                             \
   V(ScopeInfo)                                 \
   V(JSFunction)                                \
   V(Code)                                      \
@@ -1636,6 +1643,14 @@ class JSObject: public JSReceiver {
                                               Object* getter,
                                               Object* setter,
                                               PropertyAttributes attributes);
+  // Try to define a single accessor paying attention to map transitions.
+  // Returns a JavaScript null if this was not possible and we have to use the
+  // slow case. Note that we can fail due to allocations, too.
+  MUST_USE_RESULT MaybeObject* DefineFastAccessor(
+      String* name,
+      AccessorComponent component,
+      Object* accessor,
+      PropertyAttributes attributes);
   Object* LookupAccessor(String* name, AccessorComponent component);
 
   MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
@@ -2186,6 +2201,7 @@ 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,
@@ -2467,7 +2483,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 Smi* GetDetails(int descriptor_number);
+  inline PropertyDetails GetDetails(int descriptor_number);
   inline PropertyType GetType(int descriptor_number);
   inline int GetFieldIndex(int descriptor_number);
   inline JSFunction* GetConstantFunction(int descriptor_number);
@@ -2476,7 +2492,6 @@ 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:
@@ -2594,6 +2609,9 @@ class DescriptorArray: public FixedArray {
   // Is the descriptor array sorted and without duplicates?
   bool IsSortedNoDuplicates();
 
+  // Is the descriptor array consistent with the back pointers in targets?
+  bool IsConsistentWithBackPointers(Map* current_map);
+
   // Are two DescriptorArrays equal?
   bool IsEqualTo(DescriptorArray* other);
 #endif
@@ -2630,10 +2648,6 @@ 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);
@@ -3413,8 +3427,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 (named
+  // Lookup support for serialized scope info. Returns the function context
+  // slot index if the function name is present and context-allocated (named
   // function expressions, only), otherwise returns a value < 0. The name
   // must be a symbol (canonicalized).
   int FunctionContextSlotIndex(String* name, VariableMode* mode);
@@ -4243,11 +4257,6 @@ 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
@@ -4255,6 +4264,11 @@ class Code: public HeapObject {
   inline void set_allow_osr_at_loop_nesting_level(int level);
   inline int allow_osr_at_loop_nesting_level();
 
+  // [profiler_ticks]: For FUNCTION kind, tells for how many profiler ticks
+  // the code object was seen on the stack with no IC patching going on.
+  inline int profiler_ticks();
+  inline void set_profiler_ticks(int ticks);
+
   // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
   // reserved in the code prologue.
   inline unsigned stack_slots();
@@ -4289,6 +4303,11 @@ class Code: public HeapObject {
   inline byte compare_state();
   inline void set_compare_state(byte value);
 
+  // [compare_operation]: For kind COMPARE_IC tells what compare operation the
+  // stub was generated for.
+  inline byte compare_operation();
+  inline void set_compare_operation(byte value);
+
   // [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
   inline byte to_boolean_state();
   inline void set_to_boolean_state(byte value);
@@ -4423,6 +4442,8 @@ class Code: public HeapObject {
 #ifdef DEBUG
   void CodeVerify();
 #endif
+  void ClearInlineCaches();
+  void ClearTypeFeedbackCells(Heap* heap);
 
   // Max loop nesting marker used to postpose OSR. We don't take loop
   // nesting that is deeper than 5 levels into account.
@@ -4468,11 +4489,13 @@ 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;
 
+  static const int kCompareOperationOffset = kCompareStateOffset + 1;
+
   static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1;
+  static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1;
 
   static const int kSafepointTableOffsetOffset = kStackSlotsOffset + kIntSize;
   static const int kStackCheckTableOffsetOffset = kStackSlotsOffset + kIntSize;
@@ -4699,19 +4722,30 @@ class Map: public HeapObject {
   // [stub cache]: contains stubs compiled for this map.
   DECL_ACCESSORS(code_cache, Object)
 
+  // [back pointer]: points back to the parent map from which a transition
+  // leads to this map. The field overlaps with prototype transitions and the
+  // back pointer will be moved into the prototype transitions array if
+  // required.
+  inline Object* GetBackPointer();
+  inline void SetBackPointer(Object* value,
+                             WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
   // [prototype transitions]: cache of prototype transitions.
   // Prototype transition is a transition that happens
   // when we change object's prototype to a new one.
   // Cache format:
   //    0: finger - index of the first free cell in the cache
-  //    1 + 2 * i: prototype
-  //    2 + 2 * i: target map
+  //    1: back pointer that overlaps with prototype transitions field.
+  //    2 + 2 * i: prototype
+  //    3 + 2 * i: target map
   DECL_ACCESSORS(prototype_transitions, FixedArray)
 
-  inline FixedArray* unchecked_prototype_transitions();
+  inline void init_prototype_transitions(Object* undefined);
+  inline HeapObject* unchecked_prototype_transitions();
 
-  static const int kProtoTransitionHeaderSize = 1;
+  static const int kProtoTransitionHeaderSize = 2;
   static const int kProtoTransitionNumberOfEntriesOffset = 0;
+  static const int kProtoTransitionBackPointerOffset = 1;
   static const int kProtoTransitionElementsPerEntry = 2;
   static const int kProtoTransitionPrototypeOffset = 0;
   static const int kProtoTransitionMapOffset = 1;
@@ -4783,25 +4817,10 @@ class Map: public HeapObject {
   // Removes a code object from the code cache at the given index.
   void RemoveFromCodeCache(String* name, Code* code, int index);
 
-  // For every transition in this map, makes the transition's
-  // target's prototype pointer point back to this map.
-  // This is undone in MarkCompactCollector::ClearNonLiveTransitions().
-  void CreateBackPointers();
-
-  void CreateOneBackPointer(Object* transition_target);
-
-  // Set all map transitions from this map to dead maps to null.
-  // Also, restore the original prototype on the targets of these
-  // transitions, so that we do not process this map again while
-  // following back pointers.
-  void ClearNonLiveTransitions(Heap* heap, Object* real_prototype);
-
-  // Restore a possible back pointer in the prototype field of object.
-  // Return true in that case and false otherwise. Set *keep_entry to
-  // true when a live map transition has been found.
-  bool RestoreOneBackPointer(Object* object,
-                             Object* real_prototype,
-                             bool* keep_entry);
+  // Set all map transitions from this map to dead maps to null.  Also clear
+  // back pointers in transition targets so that we do not process this map
+  // again while following back pointers.
+  void ClearNonLiveTransitions(Heap* heap);
 
   // Computes a hash value for this map, to be used in HashTables and such.
   int Hash();
@@ -4883,16 +4902,17 @@ class Map: public HeapObject {
       kConstructorOffset + kPointerSize;
   static const int kCodeCacheOffset =
       kInstanceDescriptorsOrBitField3Offset + kPointerSize;
-  static const int kPrototypeTransitionsOffset =
+  static const int kPrototypeTransitionsOrBackPointerOffset =
       kCodeCacheOffset + kPointerSize;
-  static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize;
+  static const int kPadStart =
+      kPrototypeTransitionsOrBackPointerOffset + kPointerSize;
   static const int kSize = MAP_POINTER_ALIGN(kPadStart);
 
   // Layout of pointer fields. Heap iteration code relies on them
   // being continuously allocated.
   static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
   static const int kPointerFieldsEndOffset =
-      Map::kPrototypeTransitionsOffset + kPointerSize;
+      kPrototypeTransitionsOrBackPointerOffset + kPointerSize;
 
   // Byte offsets within kInstanceSizesOffset.
   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
@@ -5323,16 +5343,20 @@ class SharedFunctionInfo: public HeapObject {
   inline int compiler_hints();
   inline void set_compiler_hints(int value);
 
+  inline int ast_node_count();
+  inline void set_ast_node_count(int count);
+
   // A counter used to determine when to stress the deoptimizer with a
   // deopt.
   inline int deopt_counter();
   inline void set_deopt_counter(int counter);
 
   inline int profiler_ticks();
-  inline void set_profiler_ticks(int ticks);
 
-  inline int ast_node_count();
-  inline void set_ast_node_count(int count);
+  // Inline cache age is used to infer whether the function survived a context
+  // disposal or not. In the former case we reset the opt_count.
+  inline int ic_age();
+  inline void set_ic_age(int age);
 
   // Add information on assignments of the form this.x = ...;
   void SetThisPropertyAssignmentsInfo(
@@ -5478,6 +5502,8 @@ class SharedFunctionInfo: public HeapObject {
   void SharedFunctionInfoVerify();
 #endif
 
+  void ResetForNewContext(int new_ic_age);
+
   // Helpers to compile the shared code.  Returns true on success, false on
   // failure (e.g., stack overflow during compilation).
   static bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
@@ -5485,6 +5511,8 @@ class SharedFunctionInfo: public HeapObject {
   static bool CompileLazy(Handle<SharedFunctionInfo> shared,
                           ClearExceptionFlag flag);
 
+  void SharedFunctionInfoIterateBody(ObjectVisitor* v);
+
   // Casting.
   static inline SharedFunctionInfo* cast(Object* obj);
 
@@ -5508,12 +5536,13 @@ class SharedFunctionInfo: public HeapObject {
       kInferredNameOffset + kPointerSize;
   static const int kThisPropertyAssignmentsOffset =
       kInitialMapOffset + kPointerSize;
-  static const int kProfilerTicksOffset =
-      kThisPropertyAssignmentsOffset + kPointerSize;
+  // ic_age is a Smi field. It could be grouped with another Smi field into a
+  // PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
+  static const int kICAgeOffset = kThisPropertyAssignmentsOffset + kPointerSize;
 #if V8_HOST_ARCH_32_BIT
   // Smi fields.
   static const int kLengthOffset =
-      kProfilerTicksOffset + kPointerSize;
+      kICAgeOffset + kPointerSize;
   static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
   static const int kExpectedNofPropertiesOffset =
       kFormalParameterCountOffset + kPointerSize;
@@ -5532,8 +5561,9 @@ class SharedFunctionInfo: public HeapObject {
   static const int kOptCountOffset =
       kThisPropertyAssignmentsCountOffset + kPointerSize;
   static const int kAstNodeCountOffset = kOptCountOffset + kPointerSize;
-  static const int kDeoptCounterOffset =
-      kAstNodeCountOffset + kPointerSize;
+  static const int kDeoptCounterOffset = kAstNodeCountOffset + kPointerSize;
+
+
   // Total size.
   static const int kSize = kDeoptCounterOffset + kPointerSize;
 #else
@@ -5547,7 +5577,7 @@ class SharedFunctionInfo: public HeapObject {
   // word is not set and thus this word cannot be treated as pointer
   // to HeapObject during old space traversal.
   static const int kLengthOffset =
-      kProfilerTicksOffset + kPointerSize;
+      kICAgeOffset + kPointerSize;
   static const int kFormalParameterCountOffset =
       kLengthOffset + kIntSize;
 
@@ -5681,6 +5711,35 @@ 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:
@@ -6080,7 +6139,7 @@ class JSDate: public JSObject {
 
   // Returns the date field with the specified index.
   // See FieldIndex for the list of date fields.
-  static MaybeObject* GetField(Object* date, Smi* index);
+  static Object* GetField(Object* date, Smi* index);
 
   void SetValue(Object* value, bool is_value_nan);
 
@@ -6562,8 +6621,8 @@ class TypeFeedbackInfo: public Struct {
   inline int ic_total_count();
   inline void set_ic_total_count(int count);
 
-  inline int ic_with_typeinfo_count();
-  inline void set_ic_with_typeinfo_count(int count);
+  inline int ic_with_type_info_count();
+  inline void set_ic_with_type_info_count(int count);
 
   DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
 
@@ -7597,6 +7656,10 @@ 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);
 };
@@ -8057,6 +8120,18 @@ class AccessorPair: public Struct {
 
   MUST_USE_RESULT MaybeObject* CopyWithoutTransitions();
 
+  Object* get(AccessorComponent component) {
+    return component == ACCESSOR_GETTER ? getter() : setter();
+  }
+
+  void set(AccessorComponent component, Object* value) {
+    if (component == ACCESSOR_GETTER) {
+      set_getter(value);
+    } else {
+      set_setter(value);
+    }
+  }
+
   // Note: Returns undefined instead in case of a hole.
   Object* GetComponent(AccessorComponent component);
 
@@ -8531,6 +8606,8 @@ class ObjectVisitor BASE_EMBEDDED {
   // Visit pointer embedded into a code object.
   virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
 
+  virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
+
   // Visits a contiguous arrays of external references (references to the C++
   // heap) in the half-open range [start, end). Any or all of the values
   // may be modified on return.
index da68041..8620519 100644 (file)
@@ -1333,11 +1333,19 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
 
   Expect(Token::RBRACE, CHECK_OK);
   scope->set_end_position(scanner().location().end_pos);
-  body->set_block_scope(scope);
+  body->set_scope(scope);
 
-  scope->interface()->Freeze(ok);
+  // 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);
   ASSERT(ok);
-  return factory()->NewModuleLiteral(body, scope->interface());
+  interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok);
+  ASSERT(ok);
+  interface->Freeze(ok);
+  ASSERT(ok);
+  return factory()->NewModuleLiteral(body, interface);
 }
 
 
@@ -1403,7 +1411,14 @@ Module* Parser::ParseModuleUrl(bool* ok) {
 #ifdef DEBUG
   if (FLAG_print_interface_details) PrintF("# Url ");
 #endif
-  return factory()->NewModuleUrl(symbol);
+
+  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;
 }
 
 
@@ -2015,7 +2030,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_block_scope(block_scope);
+  body->set_scope(block_scope);
   return body;
 }
 
@@ -2254,7 +2269,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 (not even in a prototype of the global object) it
+    // doesn't exist (on the global object itself, see ES5 errata) 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
@@ -2917,7 +2932,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_block_scope(for_scope);
+        body_block->set_scope(for_scope);
         // Parsed for-in loop w/ let declaration.
         return loop;
 
@@ -2997,7 +3012,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
     Block* result = factory()->NewBlock(NULL, 2, false);
     result->AddStatement(init);
     result->AddStatement(loop);
-    result->set_block_scope(for_scope);
+    result->set_scope(for_scope);
     if (loop) loop->Initialize(NULL, cond, next, body);
     return result;
   } else {
@@ -4460,15 +4475,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
     Variable* fvar = NULL;
     Token::Value fvar_init_op = Token::INIT_CONST;
     if (type == FunctionLiteral::NAMED_EXPRESSION) {
-      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());
+      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);
     }
 
     // Determine whether the function will be lazily compiled.
index fa6fce0..089ea38 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "v8.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "v8threads.h"
 #include "vm-state-inl.h"
@@ -61,18 +62,10 @@ 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();
 }
 
-
 uint64_t OS::CpuFeaturesImpliedByPlatform() {
   return 0;  // Nothing special about Cygwin.
 }
@@ -627,8 +620,11 @@ 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_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -639,7 +635,7 @@ class SamplerThread : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -725,7 +721,7 @@ class SamplerThread : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;
 
  private:
@@ -733,10 +729,29 @@ class SamplerThread : public Thread {
 };
 
 
-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 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),
index 2a9e174..511759c 100644 (file)
@@ -54,6 +54,7 @@
 #include "v8.h"
 #include "v8threads.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "vm-state-inl.h"
 
@@ -79,15 +80,8 @@ 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();
 }
 
 
@@ -560,6 +554,7 @@ class FreeBSDMutex : public Mutex {
     ASSERT(result == 0);
     result = pthread_mutex_init(&mutex_, &attrs);
     ASSERT(result == 0);
+    USE(result);
   }
 
   virtual ~FreeBSDMutex() { pthread_mutex_destroy(&mutex_); }
@@ -722,8 +717,11 @@ 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_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Install a signal handler.
@@ -743,7 +741,7 @@ class SignalSender : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -836,7 +834,7 @@ class SignalSender : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -845,12 +843,31 @@ class SignalSender : public Thread {
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 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),
index 08f4495..f6db423 100644 (file)
@@ -46,9 +46,9 @@
 #include <sys/stat.h>   // open
 #include <fcntl.h>      // open
 #include <unistd.h>     // sysconf
-#ifdef __GLIBC__
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
 #include <execinfo.h>   // backtrace, backtrace_symbols
-#endif  // def __GLIBC__
+#endif  // defined(__GLIBC__) && !defined(__UCLIBC__)
 #include <strings.h>    // index
 #include <errno.h>
 #include <stdarg.h>
@@ -57,6 +57,7 @@
 
 #include "v8.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "v8threads.h"
 #include "vm-state-inl.h"
@@ -78,30 +79,8 @@ 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();
 }
 
 
@@ -556,7 +535,7 @@ void OS::SignalCodeMovingGC() {
 
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
   // backtrace is a glibc extension.
-#ifdef __GLIBC__
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
   int frames_size = frames.length();
   ScopedVector<void*> addresses(frames_size);
 
@@ -581,9 +560,9 @@ int OS::StackWalk(Vector<OS::StackFrame> frames) {
   free(symbols);
 
   return frames_count;
-#else  // ndef __GLIBC__
+#else  // defined(__GLIBC__) && !defined(__UCLIBC__)
   return 0;
-#endif  // ndef __GLIBC__
+#endif  // defined(__GLIBC__) && !defined(__UCLIBC__)
 }
 
 
@@ -985,6 +964,25 @@ typedef struct ucontext {
   __sigset_t uc_sigmask;
 } ucontext_t;
 
+#elif !defined(__GLIBC__) && defined(__i386__)
+// x86 version for Android.
+struct sigcontext {
+  uint32_t gregs[19];
+  void* fpregs;
+  uint32_t oldmask;
+  uint32_t cr2;
+};
+
+typedef uint32_t __sigset_t;
+typedef struct sigcontext mcontext_t;
+typedef struct ucontext {
+  uint32_t uc_flags;
+  struct ucontext* uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  __sigset_t uc_sigmask;
+} ucontext_t;
+enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
 #endif
 
 
@@ -1076,6 +1074,9 @@ 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;
@@ -1093,7 +1094,7 @@ class SignalSender : public Thread {
   }
 
   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -1106,7 +1107,7 @@ class SignalSender : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -1209,7 +1210,7 @@ class SignalSender : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -1219,12 +1220,46 @@ class SignalSender : public Thread {
 };
 
 
-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 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),
index bfcaab0..a937ed3 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "v8.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "vm-state-inl.h"
 
@@ -93,11 +94,8 @@ 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();
 }
 
 
@@ -745,8 +743,11 @@ 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_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -757,7 +758,7 @@ class SamplerThread : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -854,7 +855,7 @@ class SamplerThread : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;
 
  private:
@@ -864,10 +865,25 @@ class SamplerThread : public Thread {
 #undef REGISTER_FIELD
 
 
-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 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),
index e05345c..679ef8e 100644 (file)
@@ -86,6 +86,16 @@ void OS::SetUp() {
 }
 
 
+void OS::PostSetUp() {
+  UNIMPLEMENTED();
+}
+
+
+void OS::TearDown() {
+  UNIMPLEMENTED();
+}
+
+
 // Returns the accumulated user time for thread.
 int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
   UNIMPLEMENTED();
index b79cb71..ba33a84 100644 (file)
@@ -51,6 +51,7 @@
 
 #include "v8.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "v8threads.h"
 #include "vm-state-inl.h"
@@ -99,11 +100,8 @@ 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();
 }
 
 
@@ -795,6 +793,9 @@ 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;
@@ -812,7 +813,7 @@ class SignalSender : public Thread {
   }
 
   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -825,7 +826,7 @@ class SignalSender : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -919,7 +920,7 @@ class SignalSender : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -929,12 +930,27 @@ class SignalSender : public Thread {
 };
 
 
-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 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),
index 1f87e70..6631659 100644 (file)
@@ -29,6 +29,8 @@
 // own but contains the parts which are the same across POSIX platforms Linux,
 // Mac OS, FreeBSD and OpenBSD.
 
+#include "platform-posix.h"
+
 #include <unistd.h>
 #include <errno.h>
 #include <time.h>
@@ -129,13 +131,10 @@ double modulo(double x, double y) {
 
 #define UNARY_MATH_FUNCTION(name, generator)             \
 static UnaryMathFunction fast_##name##_function = NULL;  \
-V8_DECLARE_ONCE(fast_##name##_init_once);                \
 void init_fast_##name##_function() {                     \
   fast_##name##_function = generator;                    \
 }                                                        \
 double fast_##name(double x) {                           \
-  CallOnce(&fast_##name##_init_once,                     \
-           &init_fast_##name##_function);                \
   return (*fast_##name##_function)(x);                   \
 }
 
@@ -305,20 +304,11 @@ 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);
@@ -328,6 +318,18 @@ 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.
 //
@@ -419,11 +421,7 @@ Socket* POSIXSocket::Accept() const {
     return NULL;
   }
 
-  int socket;
-  do
-    socket = accept(socket_, NULL, NULL);
-  while (socket == -1 && errno == EINTR);
-
+  int socket = accept(socket_, NULL, NULL);
   if (socket == -1) {
     return NULL;
   } else {
@@ -450,10 +448,7 @@ bool POSIXSocket::Connect(const char* host, const char* port) {
   }
 
   // Connect.
-  do
-    status = connect(socket_, result->ai_addr, result->ai_addrlen);
-  while (status == -1 && errno == EINTR);
-
+  status = connect(socket_, result->ai_addr, result->ai_addrlen);
   freeaddrinfo(result);
   return status == 0;
 }
@@ -472,32 +467,13 @@ bool POSIXSocket::Shutdown() {
 
 
 int POSIXSocket::Send(const char* data, int len) const {
-  int written;
-
-  for (written = 0; written < len; /* empty */) {
-    int status = send(socket_, data + written, len - written, 0);
-    if (status == 0) {
-      break;
-    } else if (status > 0) {
-      written += status;
-    } else if (errno == EINTR) {
-      /* interrupted by signal, retry */
-    } else {
-      return -1;
-    }
-  }
-
-  return written;
+  int status = send(socket_, data, len, 0);
+  return status;
 }
 
 
 int POSIXSocket::Receive(char* data, int len) const {
-  int status;
-
-  do
-    status = recv(socket_, data, len, 0);
-  while (status == -1 && errno == EINTR);
-
+  int status = recv(socket_, data, len, 0);
   return status;
 }
 
diff --git a/deps/v8/src/platform-posix.h b/deps/v8/src/platform-posix.h
new file mode 100644 (file)
index 0000000..7a982ed
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_POSIX_H_
+#define V8_PLATFORM_POSIX_H_
+
+namespace v8 {
+namespace internal {
+
+// Used by platform implementation files during OS::PostSetUp().
+void POSIXPostSetUp();
+
+} }  // namespace v8::internal
+
+#endif  // V8_PLATFORM_POSIX_H_
index 50ad353..4248ea2 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "v8.h"
 
+#include "platform-posix.h"
 #include "platform.h"
 #include "v8threads.h"
 #include "vm-state-inl.h"
@@ -90,15 +91,10 @@ 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();
 }
 
 
@@ -491,12 +487,10 @@ 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);
@@ -716,6 +710,9 @@ 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;
@@ -733,7 +730,7 @@ class SignalSender : public Thread {
   }
 
   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -746,7 +743,7 @@ class SignalSender : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -840,7 +837,7 @@ class SignalSender : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -849,12 +846,31 @@ class SignalSender : public Thread {
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 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),
index 2801b71..9e377a1 100644 (file)
@@ -51,6 +51,22 @@ 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;
@@ -64,21 +80,6 @@ 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);
@@ -112,16 +113,7 @@ int strncpy_s(char* dest, size_t dest_size, const char* source, size_t count) {
   return 0;
 }
 
-
-#ifndef __MINGW64_VERSION_MAJOR
-
-inline void MemoryBarrier() {
-  int barrier = 0;
-  __asm__ __volatile__("xchgl %%eax,%0 ":"=r" (barrier));
-}
-
-#endif  // __MINGW64_VERSION_MAJOR
-
+#endif  // MINGW_HAS_SECURE_API
 
 #endif  // __MINGW32__
 
@@ -149,20 +141,11 @@ 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);
@@ -175,7 +158,6 @@ void OS::MemCopy(void* dest, const void* src, size_t size) {
 #ifdef _WIN64
 typedef double (*ModuloFunction)(double, double);
 static ModuloFunction modulo_function = NULL;
-V8_DECLARE_ONCE(modulo_function_init_once);
 // Defined in codegen-x64.cc.
 ModuloFunction CreateModuloFunction();
 
@@ -184,7 +166,6 @@ void init_modulo_function() {
 }
 
 double modulo(double x, double y) {
-  CallOnce(&modulo_function_init_once, &init_modulo_function);
   // Note: here we rely on dependent reads being ordered. This is true
   // on all architectures we currently support.
   return (*modulo_function)(x, y);
@@ -207,13 +188,10 @@ double modulo(double x, double y) {
 
 #define UNARY_MATH_FUNCTION(name, generator)             \
 static UnaryMathFunction fast_##name##_function = NULL;  \
-V8_DECLARE_ONCE(fast_##name##_init_once);                \
 void init_fast_##name##_function() {                     \
   fast_##name##_function = generator;                    \
 }                                                        \
 double fast_##name(double x) {                           \
-  CallOnce(&fast_##name##_init_once,                     \
-           &init_fast_##name##_function);                \
   return (*fast_##name##_function)(x);                   \
 }
 
@@ -226,6 +204,18 @@ UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
 #undef MATH_FUNCTION
 
 
+void MathSetup() {
+#ifdef _WIN64
+  init_modulo_function();
+#endif
+  init_fast_sin_function();
+  init_fast_cos_function();
+  init_fast_tan_function();
+  init_fast_log_function();
+  init_fast_sqrt_function();
+}
+
+
 // ----------------------------------------------------------------------------
 // The Time class represents time on win32. A timestamp is represented as
 // a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript
@@ -470,6 +460,9 @@ 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_);
@@ -511,11 +504,14 @@ 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);
 
-  return localtime.Diff(&rounded_to_second);
+  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;
+  }
 }
 
 
@@ -558,15 +554,13 @@ 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
 }
 
 
@@ -1955,8 +1949,11 @@ 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_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -1967,7 +1964,7 @@ class SamplerThread : public Thread {
   }
 
   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -2053,7 +2050,7 @@ class SamplerThread : public Thread {
   RuntimeProfilerRateLimiter rate_limiter_;
 
   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;
 
  private:
@@ -2061,10 +2058,29 @@ class SamplerThread : public Thread {
 };
 
 
-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 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),
index 4ec6057..168791a 100644 (file)
@@ -119,6 +119,13 @@ class OS {
   // Initializes the platform OS support. Called once at VM startup.
   static void SetUp();
 
+  // Initializes the platform OS support that depend on CPU features. This is
+  // 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
@@ -545,7 +552,8 @@ struct CreateMutexTrait {
 //     // Do something.
 //   }
 //
-typedef LazyDynamicInstance<Mutex, CreateMutexTrait>::type LazyMutex;
+typedef LazyDynamicInstance<
+    Mutex, CreateMutexTrait, ThreadSafeInitOnceTrait>::type LazyMutex;
 
 #define LAZY_MUTEX_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER
 
@@ -616,7 +624,8 @@ struct CreateSemaphoreTrait {
 template <int InitialValue>
 struct LazySemaphore {
   typedef typename LazyDynamicInstance<
-      Semaphore, CreateSemaphoreTrait<InitialValue> >::type type;
+      Semaphore, CreateSemaphoreTrait<InitialValue>,
+      ThreadSafeInitOnceTrait>::type type;
 };
 
 #define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER
index 20d3b9c..0c17eec 100644 (file)
@@ -581,9 +581,8 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
   ParseExpression(true, CHECK_OK);
   Expect(i::Token::RPAREN, CHECK_OK);
 
-  scope_->EnterWith();
+  Scope::InsideWith iw(scope_);
   ParseStatement(CHECK_OK);
-  scope_->LeaveWith();
   return Statement::Default();
 }
 
@@ -749,10 +748,9 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
       return Statement::Default();
     }
     Expect(i::Token::RPAREN, CHECK_OK);
-    scope_->EnterWith();
-    ParseBlock(ok);
-    scope_->LeaveWith();
-    if (!*ok) Statement::Default();
+    { Scope::InsideWith iw(scope_);
+      ParseBlock(CHECK_OK);
+    }
     catch_or_finally_seen = true;
   }
   if (peek() == i::Token::FINALLY) {
index f3a4347..13261f7 100644 (file)
@@ -470,8 +470,19 @@ class PreParser {
     void set_language_mode(i::LanguageMode language_mode) {
       language_mode_ = language_mode;
     }
-    void EnterWith() { with_nesting_count_++; }
-    void LeaveWith() { with_nesting_count_--; }
+
+    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);
+    };
 
    private:
     Scope** const variable_;
index 65369be..9afc52f 100644 (file)
@@ -95,6 +95,55 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
 }
 
 
+HeapEntry* HeapGraphEdge::from() const {
+  return &snapshot()->entries()[from_index_];
+}
+
+
+HeapSnapshot* HeapGraphEdge::snapshot() const {
+  return to_entry_->snapshot();
+}
+
+
+int HeapEntry::index() const {
+  return static_cast<int>(this - &snapshot_->entries().first());
+}
+
+
+int HeapEntry::set_children_index(int index) {
+  children_index_ = index;
+  int next_index = index + children_count_;
+  children_count_ = 0;
+  return next_index;
+}
+
+
+int HeapEntry::set_retainers_index(int index) {
+  retainers_index_ = index;
+  int next_index = index + retainers_count_;
+  retainers_count_ = 0;
+  return next_index;
+}
+
+
+HeapGraphEdge** HeapEntry::children_arr() {
+  ASSERT(children_index_ >= 0);
+  return &snapshot_->children()[children_index_];
+}
+
+
+HeapGraphEdge** HeapEntry::retainers_arr() {
+  ASSERT(retainers_index_ >= 0);
+  return &snapshot_->retainers()[retainers_index_];
+}
+
+
+HeapEntry* HeapEntry::dominator() const {
+  ASSERT(dominator_ >= 0);
+  return &snapshot_->entries()[dominator_];
+}
+
+
 SnapshotObjectId HeapObjectsMap::GetNthGcSubrootId(int delta) {
   return kGcRootsFirstSubrootId + delta * kObjectIdStep;
 }
index 2d0984e..c03e526 100644 (file)
@@ -34,6 +34,7 @@
 #include "scopeinfo.h"
 #include "unicode.h"
 #include "zone-inl.h"
+#include "debug.h"
 
 namespace v8 {
 namespace internal {
@@ -930,81 +931,71 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
 }
 
 
-void HeapGraphEdge::Init(
-    int child_index, Type type, const char* name, HeapEntry* to) {
+HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
+    : type_(type),
+      from_index_(from),
+      to_index_(to),
+      name_(name) {
   ASSERT(type == kContextVariable
-         || type == kProperty
-         || type == kInternal
-         || type == kShortcut);
-  child_index_ = child_index;
-  type_ = type;
-  name_ = name;
-  to_ = to;
+      || type == kProperty
+      || type == kInternal
+      || type == kShortcut);
 }
 
 
-void HeapGraphEdge::Init(int child_index, Type type, int index, HeapEntry* to) {
+HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to)
+    : type_(type),
+      from_index_(from),
+      to_index_(to),
+      index_(index) {
   ASSERT(type == kElement || type == kHidden || type == kWeak);
-  child_index_ = child_index;
-  type_ = type;
-  index_ = index;
-  to_ = to;
 }
 
 
-void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) {
-  Init(child_index, kElement, index, to);
+void HeapGraphEdge::ReplaceToIndexWithEntry(HeapSnapshot* snapshot) {
+  to_entry_ = &snapshot->entries()[to_index_];
 }
 
 
-HeapEntry* HeapGraphEdge::From() {
-  return reinterpret_cast<HeapEntry*>(this - child_index_) - 1;
-}
-
+const int HeapEntry::kNoEntry = -1;
 
-void HeapEntry::Init(HeapSnapshot* snapshot,
+HeapEntry::HeapEntry(HeapSnapshot* snapshot,
                      Type type,
                      const char* name,
                      SnapshotObjectId id,
-                     int self_size,
-                     int children_count,
-                     int retainers_count) {
-  snapshot_ = snapshot;
-  type_ = type;
-  painted_ = false;
-  name_ = name;
-  self_size_ = self_size;
-  retained_size_ = 0;
-  children_count_ = children_count;
-  retainers_count_ = retainers_count;
-  dominator_ = NULL;
-  id_ = id;
-}
+                     int self_size)
+    : painted_(false),
+      user_reachable_(false),
+      dominator_(kNoEntry),
+      type_(type),
+      retainers_count_(0),
+      retainers_index_(-1),
+      children_count_(0),
+      children_index_(-1),
+      self_size_(self_size),
+      retained_size_(0),
+      id_(id),
+      snapshot_(snapshot),
+      name_(name) { }
 
 
 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type,
-                                  int child_index,
                                   const char* name,
-                                  HeapEntry* entry,
-                                  int retainer_index) {
-  children()[child_index].Init(child_index, type, name, entry);
-  entry->retainers()[retainer_index] = children_arr() + child_index;
+                                  HeapEntry* entry) {
+  HeapGraphEdge edge(type, name, this->index(), entry->index());
+  snapshot_->edges().Add(edge);
+  ++children_count_;
+  ++entry->retainers_count_;
 }
 
 
 void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type,
-                                    int child_index,
                                     int index,
-                                    HeapEntry* entry,
-                                    int retainer_index) {
-  children()[child_index].Init(child_index, type, index, entry);
-  entry->retainers()[retainer_index] = children_arr() + child_index;
-}
-
-
-void HeapEntry::SetUnidirElementReference(
-    int child_index, int index, HeapEntry* entry) {
-  children()[child_index].Init(child_index, index, entry);
+                                    HeapEntry* entry) {
+  HeapGraphEdge edge(type, index, this->index(), entry->index());
+  snapshot_->edges().Add(edge);
+  ++children_count_;
+  ++entry->retainers_count_;
 }
 
 
@@ -1015,7 +1006,8 @@ Handle<HeapObject> HeapEntry::GetHeapObject() {
 
 void HeapEntry::Print(
     const char* prefix, const char* edge_name, int max_depth, int indent) {
-  OS::Print("%6d %7d @%6llu %*c %s%s: ",
+  STATIC_CHECK(sizeof(unsigned) == sizeof(id()));
+  OS::Print("%6d %7d @%6u %*c %s%s: ",
             self_size(), retained_size(), id(),
             indent, ' ', prefix, edge_name);
   if (type() != kString) {
@@ -1033,9 +1025,9 @@ void HeapEntry::Print(
     OS::Print("\"\n");
   }
   if (--max_depth == 0) return;
-  Vector<HeapGraphEdge> ch = children();
+  Vector<HeapGraphEdge*> ch = children();
   for (int i = 0; i < ch.length(); ++i) {
-    HeapGraphEdge& edge = ch[i];
+    HeapGraphEdge& edge = *ch[i];
     const char* edge_prefix = "";
     EmbeddedVector<char, 64> index;
     const char* edge_name = index.start();
@@ -1091,15 +1083,6 @@ const char* HeapEntry::TypeAsString() {
 }
 
 
-size_t HeapEntry::EntriesSize(int entries_count,
-                              int children_count,
-                              int retainers_count) {
-  return sizeof(HeapEntry) * entries_count         // NOLINT
-      + sizeof(HeapGraphEdge) * children_count     // NOLINT
-      + sizeof(HeapGraphEdge*) * retainers_count;  // NOLINT
-}
-
-
 // It is very important to keep objects that form a heap snapshot
 // as small as possible.
 namespace {  // Avoid littering the global namespace.
@@ -1108,7 +1091,7 @@ template <size_t ptr_size> struct SnapshotSizeConstants;
 
 template <> struct SnapshotSizeConstants<4> {
   static const int kExpectedHeapGraphEdgeSize = 12;
-  static const int kExpectedHeapEntrySize = 32;
+  static const int kExpectedHeapEntrySize = 40;
   static const size_t kMaxSerializableSnapshotRawSize = 256 * MB;
 };
 
@@ -1129,11 +1112,10 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
       type_(type),
       title_(title),
       uid_(uid),
-      root_entry_(NULL),
-      gc_roots_entry_(NULL),
-      natives_root_entry_(NULL),
-      raw_entries_(NULL),
-      entries_sorted_(false) {
+      root_index_(HeapEntry::kNoEntry),
+      gc_roots_index_(HeapEntry::kNoEntry),
+      natives_root_index_(HeapEntry::kNoEntry),
+      max_snapshot_js_object_id_(0) {
   STATIC_CHECK(
       sizeof(HeapGraphEdge) ==
       SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize);
@@ -1141,34 +1123,24 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
       sizeof(HeapEntry) ==
       SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize);
   for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) {
-    gc_subroot_entries_[i] = NULL;
+    gc_subroot_indexes_[i] = HeapEntry::kNoEntry;
   }
 }
 
 
-HeapSnapshot::~HeapSnapshot() {
-  DeleteArray(raw_entries_);
-}
-
-
 void HeapSnapshot::Delete() {
   collection_->RemoveSnapshot(this);
   delete this;
 }
 
 
-void HeapSnapshot::AllocateEntries(int entries_count,
-                                   int children_count,
-                                   int retainers_count) {
-  ASSERT(raw_entries_ == NULL);
-  raw_entries_size_ =
-      HeapEntry::EntriesSize(entries_count, children_count, retainers_count);
-  raw_entries_ = NewArray<char>(raw_entries_size_);
+void HeapSnapshot::RememberLastJSObjectId() {
+  max_snapshot_js_object_id_ = collection_->last_assigned_id();
 }
 
 
-static void HeapEntryClearPaint(HeapEntry** entry_ptr) {
-  (*entry_ptr)->clear_paint();
+static void HeapEntryClearPaint(HeapEntry* entry_ptr) {
+  entry_ptr->clear_paint();
 }
 
 
@@ -1177,96 +1149,102 @@ void HeapSnapshot::ClearPaint() {
 }
 
 
-HeapEntry* HeapSnapshot::AddRootEntry(int children_count) {
-  ASSERT(root_entry_ == NULL);
-  return (root_entry_ = AddEntry(HeapEntry::kObject,
-                                 "",
-                                 HeapObjectsMap::kInternalRootObjectId,
-                                 0,
-                                 children_count,
-                                 0));
+HeapEntry* HeapSnapshot::AddRootEntry() {
+  ASSERT(root_index_ == HeapEntry::kNoEntry);
+  ASSERT(entries_.is_empty());  // Root entry must be the first one.
+  HeapEntry* entry = AddEntry(HeapEntry::kObject,
+                              "",
+                              HeapObjectsMap::kInternalRootObjectId,
+                              0);
+  root_index_ = entry->index();
+  ASSERT(root_index_ == 0);
+  return entry;
 }
 
 
-HeapEntry* HeapSnapshot::AddGcRootsEntry(int children_count,
-                                         int retainers_count) {
-  ASSERT(gc_roots_entry_ == NULL);
-  return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
-                                     "(GC roots)",
-                                     HeapObjectsMap::kGcRootsObjectId,
-                                     0,
-                                     children_count,
-                                     retainers_count));
+HeapEntry* HeapSnapshot::AddGcRootsEntry() {
+  ASSERT(gc_roots_index_ == HeapEntry::kNoEntry);
+  HeapEntry* entry = AddEntry(HeapEntry::kObject,
+                              "(GC roots)",
+                              HeapObjectsMap::kGcRootsObjectId,
+                              0);
+  gc_roots_index_ = entry->index();
+  return entry;
 }
 
 
-HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag,
-                                           int children_count,
-                                           int retainers_count) {
-  ASSERT(gc_subroot_entries_[tag] == NULL);
+HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) {
+  ASSERT(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry);
   ASSERT(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags);
-  return (gc_subroot_entries_[tag] = AddEntry(
+  HeapEntry* entry = AddEntry(
       HeapEntry::kObject,
       VisitorSynchronization::kTagNames[tag],
       HeapObjectsMap::GetNthGcSubrootId(tag),
-      0,
-      children_count,
-      retainers_count));
+      0);
+  gc_subroot_indexes_[tag] = entry->index();
+  return entry;
 }
 
 
 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
                                   const char* name,
                                   SnapshotObjectId id,
-                                  int size,
-                                  int children_count,
-                                  int retainers_count) {
-  HeapEntry* entry = GetNextEntryToInit();
-  entry->Init(this, type, name, id, size, children_count, retainers_count);
-  return entry;
+                                  int size) {
+  HeapEntry entry(this, type, name, id, size);
+  entries_.Add(entry);
+  return &entries_.last();
+}
+
+
+void HeapSnapshot::FillChildrenAndRetainers() {
+  ASSERT(children().is_empty());
+  children().Allocate(edges().length());
+  ASSERT(retainers().is_empty());
+  retainers().Allocate(edges().length());
+  int children_index = 0;
+  int retainers_index = 0;
+  for (int i = 0; i < entries().length(); ++i) {
+    HeapEntry* entry = &entries()[i];
+    children_index = entry->set_children_index(children_index);
+    retainers_index = entry->set_retainers_index(retainers_index);
+  }
+  ASSERT(edges().length() == children_index);
+  ASSERT(edges().length() == retainers_index);
+  for (int i = 0; i < edges().length(); ++i) {
+    HeapGraphEdge* edge = &edges()[i];
+    edge->ReplaceToIndexWithEntry(this);
+    edge->from()->add_child(edge);
+    edge->to()->add_retainer(edge);
+  }
 }
 
 
 void HeapSnapshot::SetDominatorsToSelf() {
   for (int i = 0; i < entries_.length(); ++i) {
-    HeapEntry* entry = entries_[i];
-    if (entry->dominator() == NULL) entry->set_dominator(entry);
+    entries_[i].set_dominator(&entries_[i]);
   }
 }
 
 
-HeapEntry* HeapSnapshot::GetNextEntryToInit() {
-  if (entries_.length() > 0) {
-    HeapEntry* last_entry = entries_.last();
-    entries_.Add(reinterpret_cast<HeapEntry*>(
-        reinterpret_cast<char*>(last_entry) + last_entry->EntrySize()));
-  } else {
-    entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_));
+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;
   }
-  ASSERT(reinterpret_cast<char*>(entries_.last()) <
-         (raw_entries_ + raw_entries_size_));
-  return entries_.last();
-}
+ private:
+  SnapshotObjectId id_;
+};
 
 
 HeapEntry* HeapSnapshot::GetEntryById(SnapshotObjectId id) {
   List<HeapEntry*>* entries_by_id = GetSortedEntriesList();
-
   // Perform a binary search by id.
-  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;
+  int index = SortedListBSearch(*entries_by_id, FindEntryById(id));
+  if (index == -1)
+    return NULL;
+  return entries_by_id->at(index);
 }
 
 
@@ -1279,11 +1257,14 @@ static int SortByIds(const T* entry1_ptr,
 
 
 List<HeapEntry*>* HeapSnapshot::GetSortedEntriesList() {
-  if (!entries_sorted_) {
-    entries_.Sort(SortByIds);
-    entries_sorted_ = true;
+  if (sorted_entries_.is_empty()) {
+    sorted_entries_.Allocate(entries_.length());
+    for (int i = 0; i < entries_.length(); ++i) {
+      sorted_entries_[i] = &entries_[i];
+    }
+    sorted_entries_.Sort(SortByIds);
   }
-  return &entries_;
+  return &sorted_entries_;
 }
 
 
@@ -1292,6 +1273,22 @@ void HeapSnapshot::Print(int max_depth) {
 }
 
 
+template<typename T, class P>
+static size_t GetMemoryUsedByList(const List<T, P>& list) {
+  return list.capacity() * sizeof(T);
+}
+
+
+size_t HeapSnapshot::RawSnapshotSize() const {
+  return
+      GetMemoryUsedByList(entries_) +
+      GetMemoryUsedByList(edges_) +
+      GetMemoryUsedByList(children_) +
+      GetMemoryUsedByList(retainers_) +
+      GetMemoryUsedByList(sorted_entries_);
+}
+
+
 // We split IDs on evens for embedder objects (see
 // HeapObjectsMap::GenerateId) and odds for native objects.
 const SnapshotObjectId HeapObjectsMap::kInternalRootObjectId = 1;
@@ -1304,96 +1301,166 @@ const SnapshotObjectId HeapObjectsMap::kFirstAvailableObjectId =
     VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep;
 
 HeapObjectsMap::HeapObjectsMap()
-    : initial_fill_mode_(true),
-      next_id_(kFirstAvailableObjectId),
-      entries_map_(AddressesMatch),
-      entries_(new List<EntryInfo>()) { }
-
-
-HeapObjectsMap::~HeapObjectsMap() {
-  delete entries_;
+    : 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));
 }
 
 
 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;
-  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;
-    }
+  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;
   }
+  to_entry->value = reinterpret_cast<void*>(from_entry_info_index);
 }
 
 
-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::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;
 }
 
 
-SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) {
-  HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), false);
-  if (entry != NULL) {
+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) {
     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() {
-  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);
+  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);
     if (entry_info.accessed) {
-      entry->value = reinterpret_cast<void*>(new_entries->length());
-      new_entries->Add(EntryInfo(entry_info.id, false));
+      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;
     } else {
-      dead_entries.Add(entry->key);
+      if (entry_info.addr) {
+        entries_map_.Remove(entry_info.addr, AddressHash(entry_info.addr));
+      }
     }
   }
-  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;
+  entries_.Rewind(first_free_entry);
+  ASSERT(static_cast<uint32_t>(entries_.length()) - 1 ==
+         entries_map_.occupancy());
 }
 
 
@@ -1480,7 +1547,7 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
   for (HeapObject* obj = iterator.next();
        obj != NULL;
        obj = iterator.next()) {
-    if (ids_.FindObject(obj->address()) == id) {
+    if (ids_.FindEntry(obj->address()) == id) {
       ASSERT(object == NULL);
       object = obj;
       // Can't break -- kFilterUnreachable requires full heap traversal.
@@ -1490,80 +1557,22 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
 }
 
 
-HeapEntry* const HeapEntriesMap::kHeapEntryPlaceholder =
-    reinterpret_cast<HeapEntry*>(1);
-
 HeapEntriesMap::HeapEntriesMap()
-    : entries_(HeapThingsMatch),
-      entries_count_(0),
-      total_children_count_(0),
-      total_retainers_count_(0) {
+    : entries_(HeapThingsMatch) {
 }
 
 
-HeapEntriesMap::~HeapEntriesMap() {
-  for (HashMap::Entry* p = entries_.Start(); p != NULL; p = entries_.Next(p)) {
-    delete reinterpret_cast<EntryInfo*>(p->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(
-        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;
-  }
-}
-
-
-HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
+int HeapEntriesMap::Map(HeapThing thing) {
   HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
-  if (cache_entry != NULL) {
-    EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
-    return entry_info->entry;
-  } else {
-    return NULL;
-  }
+  if (cache_entry == NULL) return HeapEntry::kNoEntry;
+  return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
 }
 
 
-void HeapEntriesMap::Pair(
-    HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry) {
+void HeapEntriesMap::Pair(HeapThing thing, int entry) {
   HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
   ASSERT(cache_entry->value == NULL);
-  cache_entry->value = new EntryInfo(entry, allocator);
-  ++entries_count_;
-}
-
-
-void HeapEntriesMap::CountReference(HeapThing from, HeapThing to,
-                                    int* prev_children_count,
-                                    int* prev_retainers_count) {
-  HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false);
-  HashMap::Entry* to_cache_entry = entries_.Lookup(to, Hash(to), false);
-  ASSERT(from_cache_entry != NULL);
-  ASSERT(to_cache_entry != NULL);
-  EntryInfo* from_entry_info =
-      reinterpret_cast<EntryInfo*>(from_cache_entry->value);
-  EntryInfo* to_entry_info =
-      reinterpret_cast<EntryInfo*>(to_cache_entry->value);
-  if (prev_children_count)
-    *prev_children_count = from_entry_info->children_count;
-  if (prev_retainers_count)
-    *prev_retainers_count = to_entry_info->retainers_count;
-  ++from_entry_info->children_count;
-  ++to_entry_info->retainers_count;
-  ++total_children_count_;
-  ++total_retainers_count_;
+  cache_entry->value = reinterpret_cast<void*>(static_cast<intptr_t>(entry));
 }
 
 
@@ -1580,20 +1589,14 @@ void HeapObjectsSet::Clear() {
 bool HeapObjectsSet::Contains(Object* obj) {
   if (!obj->IsHeapObject()) return false;
   HeapObject* object = HeapObject::cast(obj);
-  HashMap::Entry* cache_entry =
-      entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
-  return cache_entry != NULL;
+  return entries_.Lookup(object, HeapEntriesMap::Hash(object), false) != NULL;
 }
 
 
 void HeapObjectsSet::Insert(Object* obj) {
   if (!obj->IsHeapObject()) return;
   HeapObject* object = HeapObject::cast(obj);
-  HashMap::Entry* cache_entry =
-      entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
-  if (cache_entry->value == NULL) {
-    cache_entry->value = HeapEntriesMap::kHeapEntryPlaceholder;
-  }
+  entries_.Lookup(object, HeapEntriesMap::Hash(object), true);
 }
 
 
@@ -1601,12 +1604,9 @@ const char* HeapObjectsSet::GetTag(Object* obj) {
   HeapObject* object = HeapObject::cast(obj);
   HashMap::Entry* cache_entry =
       entries_.Lookup(object, HeapEntriesMap::Hash(object), false);
-  if (cache_entry != NULL
-      && cache_entry->value != HeapEntriesMap::kHeapEntryPlaceholder) {
-    return reinterpret_cast<const char*>(cache_entry->value);
-  } else {
-    return NULL;
-  }
+  return cache_entry != NULL
+      ? reinterpret_cast<const char*>(cache_entry->value)
+      : NULL;
 }
 
 
@@ -1648,126 +1648,83 @@ V8HeapExplorer::~V8HeapExplorer() {
 }
 
 
-HeapEntry* V8HeapExplorer::AllocateEntry(
-    HeapThing ptr, int children_count, int retainers_count) {
-  return AddEntry(
-      reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
+HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) {
+  return AddEntry(reinterpret_cast<HeapObject*>(ptr));
 }
 
 
-HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
-                                    int children_count,
-                                    int retainers_count) {
+HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
   if (object == kInternalRootObject) {
-    ASSERT(retainers_count == 0);
-    return snapshot_->AddRootEntry(children_count);
+    snapshot_->AddRootEntry();
+    return snapshot_->root();
   } else if (object == kGcRootsObject) {
-    return snapshot_->AddGcRootsEntry(children_count, retainers_count);
+    HeapEntry* entry = snapshot_->AddGcRootsEntry();
+    return entry;
   } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) {
-    return snapshot_->AddGcSubrootEntry(
-        GetGcSubrootOrder(object),
-        children_count,
-        retainers_count);
+    HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object));
+    return entry;
   } else if (object->IsJSFunction()) {
     JSFunction* func = JSFunction::cast(object);
     SharedFunctionInfo* shared = func->shared();
     const char* name = shared->bound() ? "native_bind" :
         collection_->names()->GetName(String::cast(shared->name()));
-    return AddEntry(object,
-                    HeapEntry::kClosure,
-                    name,
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kClosure, name);
   } else if (object->IsJSRegExp()) {
     JSRegExp* re = JSRegExp::cast(object);
     return AddEntry(object,
                     HeapEntry::kRegExp,
-                    collection_->names()->GetName(re->Pattern()),
-                    children_count,
-                    retainers_count);
+                    collection_->names()->GetName(re->Pattern()));
   } else if (object->IsJSObject()) {
-    return AddEntry(object,
-                    HeapEntry::kObject,
-                    "",
-                    children_count,
-                    retainers_count);
+    const char* name = collection_->names()->GetName(
+        GetConstructorName(JSObject::cast(object)));
+    if (object->IsJSGlobalObject()) {
+      const char* tag = objects_tags_.GetTag(object);
+      if (tag != NULL) {
+        name = collection_->names()->GetFormatted("%s / %s", name, tag);
+      }
+    }
+    return AddEntry(object, HeapEntry::kObject, name);
   } else if (object->IsString()) {
     return AddEntry(object,
                     HeapEntry::kString,
-                    collection_->names()->GetName(String::cast(object)),
-                    children_count,
-                    retainers_count);
+                    collection_->names()->GetName(String::cast(object)));
   } else if (object->IsCode()) {
-    return AddEntry(object,
-                    HeapEntry::kCode,
-                    "",
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kCode, "");
   } else if (object->IsSharedFunctionInfo()) {
-    SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+    String* name = String::cast(SharedFunctionInfo::cast(object)->name());
     return AddEntry(object,
                     HeapEntry::kCode,
-                    collection_->names()->GetName(String::cast(shared->name())),
-                    children_count,
-                    retainers_count);
+                    collection_->names()->GetName(name));
   } else if (object->IsScript()) {
-    Script* script = Script::cast(object);
+    Object* name = Script::cast(object)->name();
     return AddEntry(object,
                     HeapEntry::kCode,
-                    script->name()->IsString() ?
-                        collection_->names()->GetName(
-                            String::cast(script->name()))
-                        : "",
-                    children_count,
-                    retainers_count);
+                    name->IsString()
+                        ? collection_->names()->GetName(String::cast(name))
+                        : "");
   } else if (object->IsGlobalContext()) {
-    return AddEntry(object,
-                    HeapEntry::kHidden,
-                    "system / GlobalContext",
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kHidden, "system / GlobalContext");
   } else if (object->IsContext()) {
-    return AddEntry(object,
-                    HeapEntry::kHidden,
-                    "system / Context",
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kHidden, "system / Context");
   } else if (object->IsFixedArray() ||
              object->IsFixedDoubleArray() ||
              object->IsByteArray() ||
              object->IsExternalArray()) {
-    const char* tag = objects_tags_.GetTag(object);
-    return AddEntry(object,
-                    HeapEntry::kArray,
-                    tag != NULL ? tag : "",
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kArray, "");
   } else if (object->IsHeapNumber()) {
-    return AddEntry(object,
-                    HeapEntry::kHeapNumber,
-                    "number",
-                    children_count,
-                    retainers_count);
+    return AddEntry(object, HeapEntry::kHeapNumber, "number");
   }
-  return AddEntry(object,
-                  HeapEntry::kHidden,
-                  GetSystemEntryName(object),
-                  children_count,
-                  retainers_count);
+  return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object));
 }
 
 
 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
                                     HeapEntry::Type type,
-                                    const char* name,
-                                    int children_count,
-                                    int retainers_count) {
-  return snapshot_->AddEntry(type,
-                             name,
-                             collection_->GetObjectId(object->address()),
-                             object->Size(),
-                             children_count,
-                             retainers_count);
+                                    const char* name) {
+  int object_size = object->Size();
+  SnapshotObjectId object_id =
+    collection_->GetObjectId(object->address(), object_size);
+  return snapshot_->AddEntry(type, name, object_id, object_size);
 }
 
 
@@ -1836,10 +1793,10 @@ class IndexedReferencesExtractor : public ObjectVisitor {
  public:
   IndexedReferencesExtractor(V8HeapExplorer* generator,
                              HeapObject* parent_obj,
-                             HeapEntry* parent_entry)
+                             int parent)
       : generator_(generator),
         parent_obj_(parent_obj),
-        parent_(parent_entry),
+        parent_(parent),
         next_index_(1) {
   }
   void VisitPointers(Object** start, Object** end) {
@@ -1868,178 +1825,40 @@ class IndexedReferencesExtractor : public ObjectVisitor {
   }
   V8HeapExplorer* generator_;
   HeapObject* parent_obj_;
-  HeapEntry* parent_;
+  int parent_;
   int next_index_;
 };
 
 
 void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
-  HeapEntry* entry = GetEntry(obj);
-  if (entry == NULL) return;  // No interest in this object.
+  HeapEntry* heap_entry = GetEntry(obj);
+  if (heap_entry == NULL) return;  // No interest in this object.
+  int entry = heap_entry->index();
 
   bool extract_indexed_refs = true;
   if (obj->IsJSGlobalProxy()) {
-    // 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());
+    ExtractJSGlobalProxyReferences(JSGlobalProxy::cast(obj));
   } else if (obj->IsJSObject()) {
-    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);
+    ExtractJSObjectReferences(entry, JSObject::cast(obj));
   } else if (obj->IsString()) {
-    if (obj->IsConsString()) {
-      ConsString* cs = ConsString::cast(obj);
-      SetInternalReference(obj, entry, 1, cs->first());
-      SetInternalReference(obj, entry, 2, cs->second());
-    }
-    if (obj->IsSlicedString()) {
-      SlicedString* ss = SlicedString::cast(obj);
-      SetInternalReference(obj, entry, "parent", ss->parent());
-    }
+    ExtractStringReferences(entry, String::cast(obj));
     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)");
-    for (int i = Context::FIRST_WEAK_SLOT;
-         i < Context::GLOBAL_CONTEXT_SLOTS;
-         ++i) {
-      SetWeakReference(obj, entry,
-                       i, context->get(i),
-                       FixedArray::OffsetOfElementAt(i));
-    }
+  } else if (obj->IsContext()) {
+    ExtractContextReferences(entry, Context::cast(obj));
   } 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);
+    ExtractMapReferences(entry, Map::cast(obj));
   } 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);
+    ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj));
   } 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);
+    ExtractScriptReferences(entry, Script::cast(obj));
   } 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);
+    ExtractCodeCacheReferences(entry, CodeCache::cast(obj));
   } 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)");
+    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);
@@ -2049,14 +1868,266 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
 }
 
 
-void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
-                                              HeapEntry* entry) {
+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(
+    int 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());
+      }
+    }
+    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);
+    }
+  } 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(int 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(int 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()) {
+    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));
+    }
+  }
+}
+
+
+void V8HeapExplorer::ExtractMapReferences(int 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);
+  }
+  if (map->unchecked_prototype_transitions()->IsFixedArray()) {
+    TagObject(map->prototype_transitions(), "(prototype transitions)");
+    SetInternalReference(map, entry,
+                         "prototype_transitions", map->prototype_transitions(),
+                         Map::kPrototypeTransitionsOrBackPointerOffset);
+  } else {
+    SetInternalReference(map, entry,
+                         "back_pointer", map->GetBackPointer(),
+                         Map::kPrototypeTransitionsOrBackPointerOffset);
+  }
+  SetInternalReference(map, entry,
+                       "code_cache", map->code_cache(),
+                       Map::kCodeCacheOffset);
+}
+
+
+void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
+    int 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(int 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(
+    int 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(int 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(
+    int entry, JSGlobalPropertyCell* cell) {
+  SetInternalReference(cell, entry, "value", cell->value());
+}
+
+
+void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
   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",
@@ -2072,6 +2143,8 @@ 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) {
@@ -2083,19 +2156,17 @@ 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;
-      ASSERT(idx == scope_info->FunctionContextSlotIndex(name, &mode));
-#endif
-      SetClosureReference(js_obj, entry, name, context->get(idx));
+      int idx = scope_info->FunctionContextSlotIndex(name, &mode);
+      if (idx >= 0) {
+        SetClosureReference(js_obj, entry, name, context->get(idx));
+      }
     }
   }
 }
 
 
-void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
-                                               HeapEntry* entry) {
+void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
   if (js_obj->HasFastProperties()) {
     DescriptorArray* descs = js_obj->map()->instance_descriptors();
     for (int i = 0; i < descs->number_of_descriptors(); i++) {
@@ -2152,15 +2223,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.
-        if (target->IsJSGlobalPropertyCell()) {
-          SetPropertyShortcutReference(js_obj,
-                                       entry,
-                                       String::cast(k),
-                                       JSGlobalPropertyCell::cast(
-                                           target)->value());
+        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);
         }
       }
     }
@@ -2168,8 +2239,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
 }
 
 
-void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
-                                              HeapEntry* entry) {
+void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
   if (js_obj->HasFastElements()) {
     FixedArray* elements = FixedArray::cast(js_obj->elements());
     int length = js_obj->IsJSArray() ?
@@ -2195,8 +2265,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
 }
 
 
-void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
-                                               HeapEntry* entry) {
+void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, int entry) {
   int length = js_obj->GetInternalFieldCount();
   for (int i = 0; i < length; ++i) {
     Object* o = js_obj->GetInternalField(i);
@@ -2322,6 +2391,7 @@ bool V8HeapExplorer::IterateAndExtractReferences(
     filler_ = NULL;
     return false;
   }
+
   SetRootGcRootsReference();
   RootsReferencesExtractor extractor;
   heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG);
@@ -2329,148 +2399,127 @@ bool V8HeapExplorer::IterateAndExtractReferences(
   heap_->IterateRoots(&extractor, VISIT_ALL);
   extractor.FillReferences(this);
   filler_ = NULL;
-  return progress_->ProgressReport(false);
-}
-
-
-bool V8HeapExplorer::IterateAndSetObjectNames(SnapshotFillerInterface* filler) {
-  HeapIterator iterator(HeapIterator::kFilterUnreachable);
-  filler_ = filler;
-  for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
-    SetObjectName(obj);
-  }
-  return true;
+  return progress_->ProgressReport(true);
 }
 
 
-void V8HeapExplorer::SetObjectName(HeapObject* object) {
-  if (!object->IsJSObject() || object->IsJSRegExp() || object->IsJSFunction()) {
-    return;
-  }
-  const char* name = collection_->names()->GetName(
-      GetConstructorName(JSObject::cast(object)));
-  if (object->IsJSGlobalObject()) {
-    const char* tag = objects_tags_.GetTag(object);
-    if (tag != NULL) {
-      name = collection_->names()->GetFormatted("%s / %s", name, tag);
-    }
-  }
-  GetEntry(object)->set_name(name);
+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,
+                                         int parent_entry,
                                          String* reference_name,
                                          Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
-                               parent_obj,
                                parent_entry,
                                collection_->names()->GetName(reference_name),
-                               child_obj,
                                child_entry);
   }
 }
 
 
 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
-                                            HeapEntry* parent_entry,
+                                            int parent_entry,
                                             const char* reference_name,
                                             Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetNamedReference(HeapGraphEdge::kShortcut,
-                               parent_obj,
                                parent_entry,
                                reference_name,
-                               child_obj,
                                child_entry);
   }
 }
 
 
 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
-                                         HeapEntry* parent_entry,
+                                         int parent_entry,
                                          int index,
                                          Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetIndexedReference(HeapGraphEdge::kElement,
-                                 parent_obj,
                                  parent_entry,
                                  index,
-                                 child_obj,
                                  child_entry);
   }
 }
 
 
 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
-                                          HeapEntry* parent_entry,
+                                          int parent_entry,
                                           const char* reference_name,
                                           Object* child_obj,
                                           int field_offset) {
   HeapEntry* child_entry = GetEntry(child_obj);
-  if (child_entry != NULL) {
+  if (child_entry == NULL) return;
+  if (IsEssentialObject(child_obj)) {
     filler_->SetNamedReference(HeapGraphEdge::kInternal,
-                               parent_obj,
                                parent_entry,
                                reference_name,
-                               child_obj,
                                child_entry);
-    IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
   }
+  IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
 }
 
 
 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
-                                          HeapEntry* parent_entry,
+                                          int parent_entry,
                                           int index,
                                           Object* child_obj,
                                           int field_offset) {
   HeapEntry* child_entry = GetEntry(child_obj);
-  if (child_entry != NULL) {
+  if (child_entry == NULL) return;
+  if (IsEssentialObject(child_obj)) {
     filler_->SetNamedReference(HeapGraphEdge::kInternal,
-                               parent_obj,
                                parent_entry,
                                collection_->names()->GetName(index),
-                               child_obj,
                                child_entry);
-    IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
   }
+  IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
 }
 
 
 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
-                                        HeapEntry* parent_entry,
+                                        int parent_entry,
                                         int index,
                                         Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
-  if (child_entry != NULL) {
+  if (child_entry != NULL && IsEssentialObject(child_obj)) {
     filler_->SetIndexedReference(HeapGraphEdge::kHidden,
-                                 parent_obj,
                                  parent_entry,
                                  index,
-                                 child_obj,
                                  child_entry);
   }
 }
 
 
 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
-                                      HeapEntry* parent_entry,
+                                      int parent_entry,
                                       int index,
                                       Object* child_obj,
                                       int field_offset) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetIndexedReference(HeapGraphEdge::kWeak,
-                                 parent_obj,
                                  parent_entry,
                                  index,
-                                 child_obj,
                                  child_entry);
     IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
   }
@@ -2478,7 +2527,7 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
 
 
 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
-                                          HeapEntry* parent_entry,
+                                          int parent_entry,
                                           String* reference_name,
                                           Object* child_obj,
                                           const char* name_format_string,
@@ -2495,10 +2544,8 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
         collection_->names()->GetName(reference_name);
 
     filler_->SetNamedReference(type,
-                               parent_obj,
                                parent_entry,
                                name,
-                               child_obj,
                                child_entry);
     IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
   }
@@ -2506,16 +2553,14 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
 
 
 void V8HeapExplorer::SetPropertyShortcutReference(HeapObject* parent_obj,
-                                                  HeapEntry* parent_entry,
+                                                  int parent_entry,
                                                   String* reference_name,
                                                   Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetNamedReference(HeapGraphEdge::kShortcut,
-                               parent_obj,
                                parent_entry,
                                collection_->names()->GetName(reference_name),
-                               child_obj,
                                child_entry);
   }
 }
@@ -2524,26 +2569,26 @@ void V8HeapExplorer::SetPropertyShortcutReference(HeapObject* parent_obj,
 void V8HeapExplorer::SetRootGcRootsReference() {
   filler_->SetIndexedAutoIndexReference(
       HeapGraphEdge::kElement,
-      kInternalRootObject, snapshot_->root(),
-      kGcRootsObject, snapshot_->gc_roots());
+      snapshot_->root()->index(),
+      snapshot_->gc_roots());
 }
 
 
-void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) {
+void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   ASSERT(child_entry != NULL);
   filler_->SetNamedAutoIndexReference(
       HeapGraphEdge::kShortcut,
-      kInternalRootObject, snapshot_->root(),
-      child_obj, child_entry);
+      snapshot_->root()->index(),
+      child_entry);
 }
 
 
 void V8HeapExplorer::SetGcRootsReference(VisitorSynchronization::SyncTag tag) {
   filler_->SetIndexedAutoIndexReference(
       HeapGraphEdge::kElement,
-      kGcRootsObject, snapshot_->gc_roots(),
-      GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag));
+      snapshot_->gc_roots()->index(),
+      snapshot_->gc_subroot(tag));
 }
 
 
@@ -2551,21 +2596,48 @@ void V8HeapExplorer::SetGcSubrootReference(
     VisitorSynchronization::SyncTag tag, bool is_weak, Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
-    filler_->SetIndexedAutoIndexReference(
-        is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement,
-        GetNthGcSubrootObject(tag), snapshot_->gc_subroot(tag),
-        child_obj, child_entry);
+    const char* name = GetStrongGcSubrootName(child_obj);
+    if (name != NULL) {
+      filler_->SetNamedReference(
+          HeapGraphEdge::kInternal,
+          snapshot_->gc_subroot(tag)->index(),
+          name,
+          child_entry);
+    } else {
+      filler_->SetIndexedAutoIndexReference(
+          is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement,
+          snapshot_->gc_subroot(tag)->index(),
+          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());
   }
+  return strong_gc_subroot_names_.GetTag(object);
 }
 
 
 void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
-  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);
+  if (IsEssentialObject(obj)) {
+    HeapEntry* entry = GetEntry(obj);
+    if (entry->name()[0] == '\0') {
+      entry->set_name(tag);
+    }
   }
 }
 
@@ -2611,7 +2683,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) &&
@@ -2655,8 +2727,7 @@ class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
       collection_(snapshot_->collection()),
       entries_type_(entries_type) {
   }
-  virtual HeapEntry* AllocateEntry(
-      HeapThing ptr, int children_count, int retainers_count);
+  virtual HeapEntry* AllocateEntry(HeapThing ptr);
  private:
   HeapSnapshot* snapshot_;
   HeapSnapshotsCollection* collection_;
@@ -2664,23 +2735,19 @@ class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
 };
 
 
-HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(
-    HeapThing ptr, int children_count, int retainers_count) {
+HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) {
   v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
   intptr_t elements = info->GetElementCount();
   intptr_t size = info->GetSizeInBytes();
+  const char* name = elements != -1
+      ? collection_->names()->GetFormatted(
+            "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements)
+      : collection_->names()->GetCopy(info->GetLabel());
   return snapshot_->AddEntry(
       entries_type_,
-      elements != -1 ?
-          collection_->names()->GetFormatted(
-              "%s / %" V8_PTR_PREFIX "d entries",
-              info->GetLabel(),
-              info->GetElementCount()) :
-          collection_->names()->GetCopy(info->GetLabel()),
+      name,
       HeapObjectsMap::GenerateId(info),
-      size != -1 ? static_cast<int>(size) : 0,
-      children_count,
-      retainers_count);
+      size != -1 ? static_cast<int>(size) : 0);
 }
 
 
@@ -2761,9 +2828,9 @@ void NativeObjectsExplorer::FillImplicitReferences() {
   for (int i = 0; i < groups->length(); ++i) {
     ImplicitRefGroup* group = groups->at(i);
     HeapObject* parent = *group->parent_;
-    HeapEntry* parent_entry =
-        filler_->FindOrAddEntry(parent, native_entries_allocator_);
-    ASSERT(parent_entry != NULL);
+    int parent_entry =
+        filler_->FindOrAddEntry(parent, native_entries_allocator_)->index();
+    ASSERT(parent_entry != HeapEntry::kNoEntry);
     Object*** children = group->children_;
     for (size_t j = 0; j < group->length_; ++j) {
       Object* child = *children[j];
@@ -2771,9 +2838,9 @@ void NativeObjectsExplorer::FillImplicitReferences() {
           filler_->FindOrAddEntry(child, native_entries_allocator_);
       filler_->SetNamedReference(
           HeapGraphEdge::kInternal,
-          parent, parent_entry,
+          parent_entry,
           "native",
-          child, child_entry);
+          child_entry);
     }
   }
 }
@@ -2851,8 +2918,9 @@ NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
                                        HEAP->HashSeed());
   HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy),
                                                 hash, true);
-  if (entry->value == NULL)
+  if (entry->value == NULL) {
     entry->value = new NativeGroupRetainedObjectInfo(label);
+  }
   return static_cast<NativeGroupRetainedObjectInfo*>(entry->value);
 }
 
@@ -2868,8 +2936,8 @@ void NativeObjectsExplorer::SetNativeRootReference(
       filler_->FindOrAddEntry(group_info, synthetic_entries_allocator_);
   filler_->SetNamedAutoIndexReference(
       HeapGraphEdge::kInternal,
-      group_info, group_entry,
-      info, child_entry);
+      group_entry->index(),
+      child_entry);
 }
 
 
@@ -2881,12 +2949,12 @@ void NativeObjectsExplorer::SetWrapperNativeReferences(
       filler_->FindOrAddEntry(info, native_entries_allocator_);
   ASSERT(info_entry != NULL);
   filler_->SetNamedReference(HeapGraphEdge::kInternal,
-                             wrapper, wrapper_entry,
+                             wrapper_entry->index(),
                              "native",
-                             info, info_entry);
+                             info_entry);
   filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
-                                        info, info_entry,
-                                        wrapper, wrapper_entry);
+                                        info_entry->index(),
+                                        wrapper_entry);
 }
 
 
@@ -2901,8 +2969,8 @@ void NativeObjectsExplorer::SetRootNativeRootsReference() {
     ASSERT(group_entry != NULL);
     filler_->SetIndexedAutoIndexReference(
         HeapGraphEdge::kElement,
-        V8HeapExplorer::kInternalRootObject, snapshot_->root(),
-        group_info, group_entry);
+        snapshot_->root()->index(),
+        group_entry);
   }
 }
 
@@ -2917,56 +2985,6 @@ void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) {
 }
 
 
-class SnapshotCounter : public SnapshotFillerInterface {
- public:
-  explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { }
-  HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
-    entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder);
-    return HeapEntriesMap::kHeapEntryPlaceholder;
-  }
-  HeapEntry* FindEntry(HeapThing ptr) {
-    return entries_->Map(ptr);
-  }
-  HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
-    HeapEntry* entry = FindEntry(ptr);
-    return entry != NULL ? entry : AddEntry(ptr, allocator);
-  }
-  void SetIndexedReference(HeapGraphEdge::Type,
-                           HeapThing parent_ptr,
-                           HeapEntry*,
-                           int,
-                           HeapThing child_ptr,
-                           HeapEntry*) {
-    entries_->CountReference(parent_ptr, child_ptr);
-  }
-  void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
-                                    HeapThing parent_ptr,
-                                    HeapEntry*,
-                                    HeapThing child_ptr,
-                                    HeapEntry*) {
-    entries_->CountReference(parent_ptr, child_ptr);
-  }
-  void SetNamedReference(HeapGraphEdge::Type,
-                         HeapThing parent_ptr,
-                         HeapEntry*,
-                         const char*,
-                         HeapThing child_ptr,
-                         HeapEntry*) {
-    entries_->CountReference(parent_ptr, child_ptr);
-  }
-  void SetNamedAutoIndexReference(HeapGraphEdge::Type,
-                                  HeapThing parent_ptr,
-                                  HeapEntry*,
-                                  HeapThing child_ptr,
-                                  HeapEntry*) {
-    entries_->CountReference(parent_ptr, child_ptr);
-  }
-
- private:
-  HeapEntriesMap* entries_;
-};
-
-
 class SnapshotFiller : public SnapshotFillerInterface {
  public:
   explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
@@ -2974,64 +2992,48 @@ class SnapshotFiller : public SnapshotFillerInterface {
         collection_(snapshot->collection()),
         entries_(entries) { }
   HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
-    UNREACHABLE();
-    return NULL;
+    HeapEntry* entry = allocator->AllocateEntry(ptr);
+    entries_->Pair(ptr, entry->index());
+    return entry;
   }
   HeapEntry* FindEntry(HeapThing ptr) {
-    return entries_->Map(ptr);
+    int index = entries_->Map(ptr);
+    return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL;
   }
   HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
     HeapEntry* entry = FindEntry(ptr);
     return entry != NULL ? entry : AddEntry(ptr, allocator);
   }
   void SetIndexedReference(HeapGraphEdge::Type type,
-                           HeapThing parent_ptr,
-                           HeapEntry* parent_entry,
+                           int parent,
                            int index,
-                           HeapThing child_ptr,
                            HeapEntry* child_entry) {
-    int child_index, retainer_index;
-    entries_->CountReference(
-        parent_ptr, child_ptr, &child_index, &retainer_index);
-    parent_entry->SetIndexedReference(
-        type, child_index, index, child_entry, retainer_index);
+    HeapEntry* parent_entry = &snapshot_->entries()[parent];
+    parent_entry->SetIndexedReference(type, index, child_entry);
   }
   void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
-                                    HeapThing parent_ptr,
-                                    HeapEntry* parent_entry,
-                                    HeapThing child_ptr,
+                                    int parent,
                                     HeapEntry* child_entry) {
-    int child_index, retainer_index;
-    entries_->CountReference(
-        parent_ptr, child_ptr, &child_index, &retainer_index);
-    parent_entry->SetIndexedReference(
-        type, child_index, child_index + 1, child_entry, retainer_index);
+    HeapEntry* parent_entry = &snapshot_->entries()[parent];
+    int index = parent_entry->children_count() + 1;
+    parent_entry->SetIndexedReference(type, index, child_entry);
   }
   void SetNamedReference(HeapGraphEdge::Type type,
-                         HeapThing parent_ptr,
-                         HeapEntry* parent_entry,
+                         int parent,
                          const char* reference_name,
-                         HeapThing child_ptr,
                          HeapEntry* child_entry) {
-    int child_index, retainer_index;
-    entries_->CountReference(
-        parent_ptr, child_ptr, &child_index, &retainer_index);
-    parent_entry->SetNamedReference(
-        type, child_index, reference_name, child_entry, retainer_index);
+    HeapEntry* parent_entry = &snapshot_->entries()[parent];
+    parent_entry->SetNamedReference(type, reference_name, child_entry);
   }
   void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
-                                  HeapThing parent_ptr,
-                                  HeapEntry* parent_entry,
-                                  HeapThing child_ptr,
+                                  int parent,
                                   HeapEntry* child_entry) {
-    int child_index, retainer_index;
-    entries_->CountReference(
-        parent_ptr, child_ptr, &child_index, &retainer_index);
-    parent_entry->SetNamedReference(type,
-                              child_index,
-                              collection_->names()->GetName(child_index + 1),
-                              child_entry,
-                              retainer_index);
+    HeapEntry* parent_entry = &snapshot_->entries()[parent];
+    int index = parent_entry->children_count() + 1;
+    parent_entry->SetNamedReference(
+        type,
+        collection_->names()->GetName(index),
+        child_entry);
   }
 
  private:
@@ -3081,30 +3083,17 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
   debug_heap->Verify();
 #endif
 
-  SetProgressTotal(2);  // 2 passes.
-
-#ifdef DEBUG
-  debug_heap->Verify();
-#endif
-
-  // Pass 1. Iterate heap contents to count entries and references.
-  if (!CountEntriesAndReferences()) return false;
+  SetProgressTotal(1);  // 1 pass.
 
 #ifdef DEBUG
   debug_heap->Verify();
 #endif
 
-  // Allocate memory for entries and references.
-  snapshot_->AllocateEntries(entries_.entries_count(),
-                             entries_.total_children_count(),
-                             entries_.total_retainers_count());
-
-  // Allocate heap objects to entries hash map.
-  entries_.AllocateEntries();
-
-  // Pass 2. Fill references.
   if (!FillReferences()) return false;
 
+  snapshot_->FillChildrenAndRetainers();
+  snapshot_->RememberLastJSObjectId();
+
   if (!SetEntriesDominators()) return false;
   if (!CalculateRetainedSizes()) return false;
 
@@ -3134,49 +3123,77 @@ bool HeapSnapshotGenerator::ProgressReport(bool force) {
 void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
   if (control_ == NULL) return;
   HeapIterator iterator(HeapIterator::kFilterUnreachable);
-  progress_total_ = (
+  progress_total_ = iterations_count * (
       v8_heap_explorer_.EstimateObjectsCount(&iterator) +
-      dom_explorer_.EstimateObjectsCount()) * iterations_count;
+      dom_explorer_.EstimateObjectsCount());
   progress_counter_ = 0;
 }
 
 
-bool HeapSnapshotGenerator::CountEntriesAndReferences() {
-  SnapshotCounter counter(&entries_);
-  v8_heap_explorer_.AddRootEntries(&counter);
-  return v8_heap_explorer_.IterateAndExtractReferences(&counter)
-      && dom_explorer_.IterateAndExtractReferences(&counter);
-}
-
-
 bool HeapSnapshotGenerator::FillReferences() {
   SnapshotFiller filler(snapshot_, &entries_);
-  // IterateAndExtractReferences cannot set object names because
-  // it makes call to JSObject::LocalLookupRealNamedProperty which
-  // in turn may relocate objects in property maps thus changing the heap
-  // layout and affecting retainer counts. This is not acceptable because
-  // number of retainers must not change between count and fill passes.
-  // To avoid this there's a separate postpass that set object names.
+  v8_heap_explorer_.AddRootEntries(&filler);
   return v8_heap_explorer_.IterateAndExtractReferences(&filler)
-      && dom_explorer_.IterateAndExtractReferences(&filler)
-      && v8_heap_explorer_.IterateAndSetObjectNames(&filler);
+      && dom_explorer_.IterateAndExtractReferences(&filler);
 }
 
 
-void HeapSnapshotGenerator::FillReversePostorderIndexes(
+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(
     Vector<HeapEntry*>* entries) {
   snapshot_->ClearPaint();
   int current_entry = 0;
   List<HeapEntry*> nodes_to_visit;
-  nodes_to_visit.Add(snapshot_->root());
+  HeapEntry* root = snapshot_->root();
+  nodes_to_visit.Add(root);
   snapshot_->root()->paint();
   while (!nodes_to_visit.is_empty()) {
     HeapEntry* entry = nodes_to_visit.last();
-    Vector<HeapGraphEdge> children = entry->children();
+    Vector<HeapGraphEdge*> children = entry->children();
     bool has_new_edges = false;
     for (int i = 0; i < children.length(); ++i) {
-      if (children[i].type() == HeapGraphEdge::kShortcut) continue;
-      HeapEntry* child = children[i].to();
+      if (entry != root && !IsRetainingEdge(children[i])) continue;
+      HeapEntry* child = children[i]->to();
       if (!child->painted()) {
         nodes_to_visit.Add(child);
         child->paint();
@@ -3184,7 +3201,7 @@ void HeapSnapshotGenerator::FillReversePostorderIndexes(
       }
     }
     if (!has_new_edges) {
-      entry->set_ordered_index(current_entry);
+      entry->set_postorder_index(current_entry);
       (*entries)[current_entry++] = entry;
       nodes_to_visit.RemoveLast();
     }
@@ -3210,9 +3227,9 @@ 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;
+  for (int i = 0; i < root_index; ++i) (*dominators)[i] = HeapEntry::kNoEntry;
   (*dominators)[root_index] = root_index;
 
   // The affected array is used to mark entries which dominators
@@ -3220,28 +3237,28 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
   ScopedVector<bool> affected(entries_length);
   for (int i = 0; i < affected.length(); ++i) affected[i] = false;
   // Mark the root direct children as affected.
-  Vector<HeapGraphEdge> children = entries[root_index]->children();
+  Vector<HeapGraphEdge*> children = entries[root_index]->children();
   for (int i = 0; i < children.length(); ++i) {
-    affected[children[i].to()->ordered_index()] = true;
+    affected[children[i]->to()->postorder_index()] = true;
   }
 
   bool changed = true;
   while (changed) {
     changed = false;
-    if (!ProgressReport(true)) return false;
+    if (!ProgressReport(false)) return false;
     for (int i = root_index - 1; i >= 0; --i) {
       if (!affected[i]) continue;
       affected[i] = false;
       // If dominator of the entry has already been set to root,
       // then it can't propagate any further.
       if ((*dominators)[i] == root_index) continue;
-      int new_idom_index = kNoDominator;
+      int new_idom_index = HeapEntry::kNoEntry;
       Vector<HeapGraphEdge*> rets = entries[i]->retainers();
       for (int j = 0; j < rets.length(); ++j) {
-        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
+        if (rets[j]->from() != root && !IsRetainingEdge(rets[j])) continue;
+        int ret_index = rets[j]->from()->postorder_index();
+        if (dominators->at(ret_index) != HeapEntry::kNoEntry) {
+          new_idom_index = new_idom_index == HeapEntry::kNoEntry
               ? ret_index
               : Intersect(ret_index, new_idom_index, *dominators);
           // If idom has already reached the root, it doesn't make sense
@@ -3249,13 +3266,13 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
           if (new_idom_index == root_index) break;
         }
       }
-      if (new_idom_index != kNoDominator
+      if (new_idom_index != HeapEntry::kNoEntry
           && dominators->at(i) != new_idom_index) {
         (*dominators)[i] = new_idom_index;
         changed = true;
-        Vector<HeapGraphEdge> children = entries[i]->children();
+        Vector<HeapGraphEdge*> children = entries[i]->children();
         for (int j = 0; j < children.length(); ++j) {
-          affected[children[j].to()->ordered_index()] = true;
+          affected[children[j]->to()->postorder_index()] = true;
         }
       }
     }
@@ -3265,13 +3282,14 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
 
 
 bool HeapSnapshotGenerator::SetEntriesDominators() {
-  // This array is used for maintaining reverse postorder of nodes.
-  ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
-  FillReversePostorderIndexes(&ordered_entries);
+  MarkUserReachableObjects();
+  // This array is used for maintaining postorder of nodes.
+  ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries().length());
+  FillPostorderIndexes(&ordered_entries);
   ScopedVector<int> dominators(ordered_entries.length());
   if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
   for (int i = 0; i < ordered_entries.length(); ++i) {
-    ASSERT(dominators[i] >= 0);
+    ASSERT(dominators[i] != HeapEntry::kNoEntry);
     ordered_entries[i]->set_dominator(ordered_entries[dominators[i]]);
   }
   return true;
@@ -3282,17 +3300,18 @@ bool HeapSnapshotGenerator::CalculateRetainedSizes() {
   // As for the dominators tree we only know parent nodes, not
   // children, to sum up total sizes we "bubble" node's self size
   // adding it to all of its parents.
-  List<HeapEntry*>& entries = *snapshot_->entries();
+  List<HeapEntry>& entries = snapshot_->entries();
   for (int i = 0; i < entries.length(); ++i) {
-    HeapEntry* entry = entries[i];
+    HeapEntry* entry = &entries[i];
     entry->set_retained_size(entry->self_size());
   }
   for (int i = 0; i < entries.length(); ++i) {
-    HeapEntry* entry = entries[i];
-    int entry_size = entry->self_size();
-    for (HeapEntry* dominator = entry->dominator();
-         dominator != entry;
-         entry = dominator, dominator = entry->dominator()) {
+    int entry_size = entries[i].self_size();
+    HeapEntry* current = &entries[i];
+    for (HeapEntry* dominator = current->dominator();
+         dominator != current;
+         current = dominator, dominator = current->dominator()) {
+      ASSERT(current->dominator() != NULL);
       dominator->add_retained_size(entry_size);
     }
   }
@@ -3345,9 +3364,7 @@ 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_);
@@ -3398,20 +3415,23 @@ class OutputStreamWriter {
 };
 
 
+// type, name|index, to_node.
+const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3;
+// type, name, id, self_size, retained_size, dominator, children_index.
+const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 7;
+
 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
   ASSERT(writer_ == NULL);
   writer_ = new OutputStreamWriter(stream);
 
   HeapSnapshot* original_snapshot = NULL;
-  if (snapshot_->raw_entries_size() >=
+  if (snapshot_->RawSnapshotSize() >=
       SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize) {
     // The snapshot is too big. Serialize a fake snapshot.
     original_snapshot = snapshot_;
     snapshot_ = CreateFakeSnapshot();
   }
-  // Since nodes graph is cyclic, we need the first pass to enumerate
-  // them. Strings can be serialized in one pass.
-  EnumerateNodes();
+
   SerializeImpl();
 
   delete writer_;
@@ -3429,30 +3449,35 @@ HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() {
                                           HeapSnapshot::kFull,
                                           snapshot_->title(),
                                           snapshot_->uid());
-  result->AllocateEntries(2, 1, 0);
-  HeapEntry* root = result->AddRootEntry(1);
+  result->AddRootEntry();
   const char* text = snapshot_->collection()->names()->GetFormatted(
       "The snapshot is too big. "
       "Maximum snapshot size is %"  V8_PTR_PREFIX "u MB. "
       "Actual snapshot size is %"  V8_PTR_PREFIX "u MB.",
       SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB,
-      (snapshot_->raw_entries_size() + MB - 1) / MB);
-  HeapEntry* message = result->AddEntry(
-      HeapEntry::kString, text, 0, 4, 0, 0);
-  root->SetUnidirElementReference(0, 1, message);
+      (snapshot_->RawSnapshotSize() + MB - 1) / MB);
+  HeapEntry* message = result->AddEntry(HeapEntry::kString, text, 0, 4);
+  result->root()->SetIndexedReference(HeapGraphEdge::kElement, 1, message);
+  result->FillChildrenAndRetainers();
   result->SetDominatorsToSelf();
   return result;
 }
 
 
 void HeapSnapshotJSONSerializer::SerializeImpl() {
+  List<HeapEntry>& nodes = snapshot_->entries();
+  ASSERT(0 == snapshot_->root()->index());
   writer_->AddCharacter('{');
   writer_->AddString("\"snapshot\":{");
   SerializeSnapshot();
   if (writer_->aborted()) return;
   writer_->AddString("},\n");
   writer_->AddString("\"nodes\":[");
-  SerializeNodes();
+  SerializeNodes(nodes);
+  if (writer_->aborted()) return;
+  writer_->AddString("],\n");
+  writer_->AddString("\"edges\":[");
+  SerializeEdges(nodes);
   if (writer_->aborted()) return;
   writer_->AddString("],\n");
   writer_->AddString("\"strings\":[");
@@ -3464,34 +3489,6 @@ void HeapSnapshotJSONSerializer::SerializeImpl() {
 }
 
 
-class HeapSnapshotJSONSerializerEnumerator {
- public:
-  explicit HeapSnapshotJSONSerializerEnumerator(HeapSnapshotJSONSerializer* s)
-      : s_(s) {
-  }
-  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);
-}
-
-
-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 HeapSnapshotJSONSerializer::GetStringId(const char* s) {
   HashMap::Entry* cache_entry = strings_.Lookup(
       const_cast<char*>(s), ObjectHash(s), true);
@@ -3502,7 +3499,26 @@ int HeapSnapshotJSONSerializer::GetStringId(const char* s) {
 }
 
 
-void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) {
+static int utoa(unsigned value, const Vector<char>& buffer, int buffer_pos) {
+  int number_of_digits = 0;
+  unsigned 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;
+}
+
+
+void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
+                                               bool first_edge) {
   // The buffer needs space for 3 ints, 3 commas and \0
   static const int kBufferSize =
       MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1;  // NOLINT
@@ -3511,125 +3527,71 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) {
       || edge->type() == HeapGraphEdge::kHidden
       || edge->type() == HeapGraphEdge::kWeak
       ? edge->index() : GetStringId(edge->name());
-  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);
+  int buffer_pos = 0;
+  if (!first_edge) {
+    buffer[buffer_pos++] = ',';
+  }
+  buffer_pos = utoa(edge->type(), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(edge_name_or_index, buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos);
+  buffer[buffer_pos++] = '\0';
   writer_->AddString(buffer.start());
 }
 
 
-void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) {
+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) {
   // 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;
-  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);
+  int buffer_pos = 0;
+  if (entry_index(entry) != 0) {
+    buffer[buffer_pos++] = ',';
+  }
+  buffer_pos = utoa(entry->type(), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(entry->id(), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(entry->self_size(), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(entry->retained_size(), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(entry_index(entry->dominator()), buffer, buffer_pos);
+  buffer[buffer_pos++] = ',';
+  buffer_pos = utoa(edges_index, buffer, buffer_pos);
+  buffer[buffer_pos++] = '\n';
+  buffer[buffer_pos++] = '\0';
   writer_->AddString(buffer.start());
-  for (int i = 0; i < children.length(); ++i) {
-    SerializeEdge(&children[i]);
-    if (writer_->aborted()) return;
-  }
 }
 
 
-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.
-  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));
+void HeapSnapshotJSONSerializer::SerializeNodes(const List<HeapEntry>& nodes) {
+  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() * kEdgeFieldsCount;
     if (writer_->aborted()) return;
   }
 }
@@ -3641,6 +3603,61 @@ 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_->edges().length());
 }
 
 
index d9a1319..92896c2 100644 (file)
@@ -35,8 +35,6 @@
 namespace v8 {
 namespace internal {
 
-typedef uint32_t SnapshotObjectId;
-
 class TokenEnumerator {
  public:
   TokenEnumerator();
@@ -448,6 +446,7 @@ class ProfileGenerator {
 
 
 class HeapEntry;
+class HeapSnapshot;
 
 class HeapGraphEdge BASE_EMBEDDED {
  public:
@@ -462,60 +461,45 @@ class HeapGraphEdge BASE_EMBEDDED {
   };
 
   HeapGraphEdge() { }
-  void Init(int child_index, Type type, const char* name, HeapEntry* to);
-  void Init(int child_index, Type type, int index, HeapEntry* to);
-  void Init(int child_index, int index, HeapEntry* to);
+  HeapGraphEdge(Type type, const char* name, int from, int to);
+  HeapGraphEdge(Type type, int index, int from, int to);
+  void ReplaceToIndexWithEntry(HeapSnapshot* snapshot);
 
-  Type type() { return static_cast<Type>(type_); }
-  int index() {
+  Type type() const { return static_cast<Type>(type_); }
+  int index() const {
     ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak);
     return index_;
   }
-  const char* name() {
+  const char* name() const {
     ASSERT(type_ == kContextVariable
-           || type_ == kProperty
-           || type_ == kInternal
-           || type_ == kShortcut);
+        || type_ == kProperty
+        || type_ == kInternal
+        || type_ == kShortcut);
     return name_;
   }
-  HeapEntry* to() { return to_; }
-
-  HeapEntry* From();
+  INLINE(HeapEntry* from() const);
+  HeapEntry* to() const { return to_entry_; }
 
  private:
-  int child_index_ : 29;
+  INLINE(HeapSnapshot* snapshot() const);
+
   unsigned type_ : 3;
+  int from_index_ : 29;
+  union {
+    // During entries population |to_index_| is used for storing the index,
+    // afterwards it is replaced with a pointer to the entry.
+    int to_index_;
+    HeapEntry* to_entry_;
+  };
   union {
     int index_;
     const char* name_;
   };
-  HeapEntry* to_;
-
-  DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge);
 };
 
 
-class HeapSnapshot;
-
 // HeapEntry instances represent an entity from the heap (or a special
-// virtual node, e.g. root). To make heap snapshots more compact,
-// HeapEntries has a special memory layout (no Vectors or Lists used):
-//
-//   +-----------------+
-//        HeapEntry
-//   +-----------------+
-//      HeapGraphEdge    |
-//           ...         } children_count
-//      HeapGraphEdge    |
-//   +-----------------+
-//      HeapGraphEdge*   |
-//           ...         } retainers_count
-//      HeapGraphEdge*   |
-//   +-----------------+
-//
-// In a HeapSnapshot, all entries are hand-allocated in a continuous array
-// of raw bytes.
-//
+// virtual node, e.g. root).
 class HeapEntry BASE_EMBEDDED {
  public:
   enum Type {
@@ -530,15 +514,14 @@ class HeapEntry BASE_EMBEDDED {
     kNative = v8::HeapGraphNode::kNative,
     kSynthetic = v8::HeapGraphNode::kSynthetic
   };
+  static const int kNoEntry;
 
   HeapEntry() { }
-  void Init(HeapSnapshot* snapshot,
+  HeapEntry(HeapSnapshot* snapshot,
             Type type,
             const char* name,
             SnapshotObjectId id,
-            int self_size,
-            int children_count,
-            int retainers_count);
+            int self_size);
 
   HeapSnapshot* snapshot() { return snapshot_; }
   Type type() { return static_cast<Type>(type_); }
@@ -548,72 +531,65 @@ class HeapEntry BASE_EMBEDDED {
   int self_size() { return self_size_; }
   int retained_size() { return retained_size_; }
   void add_retained_size(int size) { retained_size_ += size; }
-  void set_retained_size(int value) { retained_size_ = value; }
-  int ordered_index() { return ordered_index_; }
-  void set_ordered_index(int value) { ordered_index_ = value; }
-
-  Vector<HeapGraphEdge> children() {
-    return Vector<HeapGraphEdge>(children_arr(), children_count_); }
+  void set_retained_size(int size) { retained_size_ = size; }
+  INLINE(int index() const);
+  int postorder_index() { return postorder_index_; }
+  void set_postorder_index(int value) { postorder_index_ = value; }
+  int children_count() const { return children_count_; }
+  INLINE(int set_children_index(int index));
+  INLINE(int set_retainers_index(int index));
+  void add_child(HeapGraphEdge* edge) {
+    children_arr()[children_count_++] = edge;
+  }
+  void add_retainer(HeapGraphEdge* edge) {
+    retainers_arr()[retainers_count_++] = edge;
+  }
+  Vector<HeapGraphEdge*> children() {
+    return Vector<HeapGraphEdge*>(children_arr(), children_count_); }
   Vector<HeapGraphEdge*> retainers() {
     return Vector<HeapGraphEdge*>(retainers_arr(), retainers_count_); }
-  HeapEntry* dominator() { return dominator_; }
+  INLINE(HeapEntry* dominator() const);
   void set_dominator(HeapEntry* entry) {
     ASSERT(entry != NULL);
-    dominator_ = entry;
+    dominator_ = entry->index();
   }
   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,
-                           int index,
-                           HeapEntry* entry,
-                           int retainer_index);
-  void SetNamedReference(HeapGraphEdge::Type type,
-                         int child_index,
-                         const char* name,
-                         HeapEntry* entry,
-                         int retainer_index);
-  void SetUnidirElementReference(int child_index, int index, HeapEntry* entry);
-
-  size_t EntrySize() {
-    return EntriesSize(1, children_count_, retainers_count_);
-  }
+  void SetIndexedReference(
+      HeapGraphEdge::Type type, int index, HeapEntry* entry);
+  void SetNamedReference(
+      HeapGraphEdge::Type type, const char* name, HeapEntry* entry);
 
   void Print(
       const char* prefix, const char* edge_name, int max_depth, int indent);
 
   Handle<HeapObject> GetHeapObject();
 
-  static size_t EntriesSize(int entries_count,
-                            int children_count,
-                            int retainers_count);
-
  private:
-  HeapGraphEdge* children_arr() {
-    return reinterpret_cast<HeapGraphEdge*>(this + 1);
-  }
-  HeapGraphEdge** retainers_arr() {
-    return reinterpret_cast<HeapGraphEdge**>(children_arr() + children_count_);
-  }
+  INLINE(HeapGraphEdge** children_arr());
+  INLINE(HeapGraphEdge** retainers_arr());
   const char* TypeAsString();
 
   unsigned painted_: 1;
+  unsigned user_reachable_: 1;
+  int dominator_: 30;
   unsigned type_: 4;
-  int children_count_: 27;
-  int retainers_count_;
+  int retainers_count_: 28;
+  int retainers_index_;
+  int children_count_;
+  int children_index_;
   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 postorder_index_;  // Used during dominator tree building.
+    int retained_size_;    // At that moment, there is no retained size yet.
   };
   SnapshotObjectId id_;
-  HeapEntry* dominator_;
   HeapSnapshot* snapshot_;
   const char* name_;
-
-  DISALLOW_COPY_AND_ASSIGN(HeapEntry);
 };
 
 
@@ -634,59 +610,60 @@ class HeapSnapshot {
                Type type,
                const char* title,
                unsigned uid);
-  ~HeapSnapshot();
   void Delete();
 
   HeapSnapshotsCollection* collection() { return collection_; }
   Type type() { return type_; }
   const char* title() { return title_; }
   unsigned uid() { return uid_; }
-  HeapEntry* root() { return root_entry_; }
-  HeapEntry* gc_roots() { return gc_roots_entry_; }
-  HeapEntry* natives_root() { return natives_root_entry_; }
-  HeapEntry* gc_subroot(int index) { return gc_subroot_entries_[index]; }
-  List<HeapEntry*>* entries() { return &entries_; }
-  size_t raw_entries_size() { return raw_entries_size_; }
-
-  void AllocateEntries(
-      int entries_count, int children_count, int retainers_count);
+  size_t RawSnapshotSize() const;
+  HeapEntry* root() { return &entries_[root_index_]; }
+  HeapEntry* gc_roots() { return &entries_[gc_roots_index_]; }
+  HeapEntry* natives_root() { return &entries_[natives_root_index_]; }
+  HeapEntry* gc_subroot(int index) {
+    return &entries_[gc_subroot_indexes_[index]];
+  }
+  List<HeapEntry>& entries() { return entries_; }
+  List<HeapGraphEdge>& edges() { return edges_; }
+  List<HeapGraphEdge*>& children() { return children_; }
+  List<HeapGraphEdge*>& retainers() { return retainers_; }
+  void RememberLastJSObjectId();
+  SnapshotObjectId max_snapshot_js_object_id() const {
+    return max_snapshot_js_object_id_;
+  }
+
   HeapEntry* AddEntry(HeapEntry::Type type,
                       const char* name,
                       SnapshotObjectId id,
-                      int size,
-                      int children_count,
-                      int retainers_count);
-  HeapEntry* AddRootEntry(int children_count);
-  HeapEntry* AddGcRootsEntry(int children_count, int retainers_count);
-  HeapEntry* AddGcSubrootEntry(int tag,
-                               int children_count,
-                               int retainers_count);
-  HeapEntry* AddNativesRootEntry(int children_count, int retainers_count);
+                      int size);
+  HeapEntry* AddRootEntry();
+  HeapEntry* AddGcRootsEntry();
+  HeapEntry* AddGcSubrootEntry(int tag);
+  HeapEntry* AddNativesRootEntry();
   void ClearPaint();
   HeapEntry* GetEntryById(SnapshotObjectId id);
   List<HeapEntry*>* GetSortedEntriesList();
-  template<class Visitor>
-  void IterateEntries(Visitor* visitor) { entries_.Iterate(visitor); }
   void SetDominatorsToSelf();
+  void FillChildrenAndRetainers();
 
   void Print(int max_depth);
   void PrintEntriesSize();
 
  private:
-  HeapEntry* GetNextEntryToInit();
-
   HeapSnapshotsCollection* collection_;
   Type type_;
   const char* title_;
   unsigned uid_;
-  HeapEntry* root_entry_;
-  HeapEntry* gc_roots_entry_;
-  HeapEntry* natives_root_entry_;
-  HeapEntry* gc_subroot_entries_[VisitorSynchronization::kNumberOfSyncTags];
-  char* raw_entries_;
-  List<HeapEntry*> entries_;
-  bool entries_sorted_;
-  size_t raw_entries_size_;
+  int root_index_;
+  int gc_roots_index_;
+  int natives_root_index_;
+  int gc_subroot_indexes_[VisitorSynchronization::kNumberOfSyncTags];
+  List<HeapEntry> entries_;
+  List<HeapGraphEdge> edges_;
+  List<HeapGraphEdge*> children_;
+  List<HeapGraphEdge*> retainers_;
+  List<HeapEntry*> sorted_entries_;
+  SnapshotObjectId max_snapshot_js_object_id_;
 
   friend class HeapSnapshotTester;
 
@@ -697,11 +674,17 @@ class HeapSnapshot {
 class HeapObjectsMap {
  public:
   HeapObjectsMap();
-  ~HeapObjectsMap();
 
   void SnapshotGenerationFinished();
-  SnapshotObjectId FindObject(Address addr);
+  SnapshotObjectId FindEntry(Address addr);
+  SnapshotObjectId FindOrAddEntry(Address addr, unsigned int size);
   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);
@@ -715,16 +698,23 @@ class HeapObjectsMap {
 
  private:
   struct EntryInfo {
-    explicit EntryInfo(SnapshotObjectId id) : id(id), accessed(true) { }
-    EntryInfo(SnapshotObjectId id, bool accessed)
-      : id(id),
-        accessed(accessed) { }
+  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) { }
     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 AddEntry(Address addr, SnapshotObjectId id);
-  SnapshotObjectId FindEntry(Address addr);
+  void UpdateHeapObjectsMap();
   void RemoveDeadEntries();
 
   static bool AddressesMatch(void* key1, void* key2) {
@@ -737,10 +727,10 @@ class HeapObjectsMap {
         v8::internal::kZeroHashSeed);
   }
 
-  bool initial_fill_mode_;
   SnapshotObjectId next_id_;
   HashMap entries_map_;
-  List<EntryInfo>* entries_;
+  List<EntryInfo> entries_;
+  List<TimeInterval> time_intervals_;
 
   DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap);
 };
@@ -752,6 +742,11 @@ 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);
@@ -763,9 +758,17 @@ class HeapSnapshotsCollection {
   StringsStorage* names() { return &names_; }
   TokenEnumerator* token_enumerator() { return token_enumerator_; }
 
-  SnapshotObjectId GetObjectId(Address addr) { return ids_.FindObject(addr); }
+  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);
+  }
   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)) {
@@ -794,8 +797,7 @@ typedef void* HeapThing;
 class HeapEntriesAllocator {
  public:
   virtual ~HeapEntriesAllocator() { }
-  virtual HeapEntry* AllocateEntry(
-      HeapThing ptr, int children_count, int retainers_count) = 0;
+  virtual HeapEntry* AllocateEntry(HeapThing ptr) = 0;
 };
 
 
@@ -804,35 +806,11 @@ class HeapEntriesAllocator {
 class HeapEntriesMap {
  public:
   HeapEntriesMap();
-  ~HeapEntriesMap();
 
-  void AllocateEntries();
-  HeapEntry* Map(HeapThing thing);
-  void Pair(HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry);
-  void CountReference(HeapThing from, HeapThing to,
-                      int* prev_children_count = NULL,
-                      int* prev_retainers_count = NULL);
-
-  int entries_count() { return entries_count_; }
-  int total_children_count() { return total_children_count_; }
-  int total_retainers_count() { return total_retainers_count_; }
-
-  static HeapEntry* const kHeapEntryPlaceholder;
+  int Map(HeapThing thing);
+  void Pair(HeapThing thing, int entry);
 
  private:
-  struct EntryInfo {
-    EntryInfo(HeapEntry* entry, HeapEntriesAllocator* allocator)
-        : entry(entry),
-          allocator(allocator),
-          children_count(0),
-          retainers_count(0) {
-    }
-    HeapEntry* entry;
-    HeapEntriesAllocator* allocator;
-    int children_count;
-    int retainers_count;
-  };
-
   static uint32_t Hash(HeapThing thing) {
     return ComputeIntegerHash(
         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)),
@@ -843,9 +821,6 @@ class HeapEntriesMap {
   }
 
   HashMap entries_;
-  int entries_count_;
-  int total_children_count_;
-  int total_retainers_count_;
 
   friend class HeapObjectsSet;
 
@@ -861,6 +836,7 @@ 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_;
@@ -879,26 +855,18 @@ class SnapshotFillerInterface {
   virtual HeapEntry* FindOrAddEntry(HeapThing ptr,
                                     HeapEntriesAllocator* allocator) = 0;
   virtual void SetIndexedReference(HeapGraphEdge::Type type,
-                                   HeapThing parent_ptr,
-                                   HeapEntry* parent_entry,
+                                   int parent_entry,
                                    int index,
-                                   HeapThing child_ptr,
                                    HeapEntry* child_entry) = 0;
   virtual void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
-                                            HeapThing parent_ptr,
-                                            HeapEntry* parent_entry,
-                                            HeapThing child_ptr,
+                                            int parent_entry,
                                             HeapEntry* child_entry) = 0;
   virtual void SetNamedReference(HeapGraphEdge::Type type,
-                                 HeapThing parent_ptr,
-                                 HeapEntry* parent_entry,
+                                 int parent_entry,
                                  const char* reference_name,
-                                 HeapThing child_ptr,
                                  HeapEntry* child_entry) = 0;
   virtual void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
-                                          HeapThing parent_ptr,
-                                          HeapEntry* parent_entry,
-                                          HeapThing child_ptr,
+                                          int parent_entry,
                                           HeapEntry* child_entry) = 0;
 };
 
@@ -917,12 +885,10 @@ class V8HeapExplorer : public HeapEntriesAllocator {
   V8HeapExplorer(HeapSnapshot* snapshot,
                  SnapshottingProgressReportingInterface* progress);
   virtual ~V8HeapExplorer();
-  virtual HeapEntry* AllocateEntry(
-      HeapThing ptr, int children_count, int retainers_count);
+  virtual HeapEntry* AllocateEntry(HeapThing ptr);
   void AddRootEntries(SnapshotFillerInterface* filler);
   int EstimateObjectsCount(HeapIterator* iterator);
   bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
-  bool IterateAndSetObjectNames(SnapshotFillerInterface* filler);
   void TagGlobalObjects();
 
   static String* GetConstructorName(JSObject* object);
@@ -930,66 +896,77 @@ class V8HeapExplorer : public HeapEntriesAllocator {
   static HeapObject* const kInternalRootObject;
 
  private:
-  HeapEntry* AddEntry(
-      HeapObject* object, int children_count, int retainers_count);
+  HeapEntry* AddEntry(HeapObject* object);
   HeapEntry* AddEntry(HeapObject* object,
                       HeapEntry::Type type,
-                      const char* name,
-                      int children_count,
-                      int retainers_count);
+                      const char* name);
   const char* GetSystemEntryName(HeapObject* object);
+
   void ExtractReferences(HeapObject* obj);
-  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);
+  void ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy);
+  void ExtractJSObjectReferences(int entry, JSObject* js_obj);
+  void ExtractStringReferences(int entry, String* obj);
+  void ExtractContextReferences(int entry, Context* context);
+  void ExtractMapReferences(int entry, Map* map);
+  void ExtractSharedFunctionInfoReferences(int entry,
+                                           SharedFunctionInfo* shared);
+  void ExtractScriptReferences(int entry, Script* script);
+  void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
+  void ExtractCodeReferences(int entry, Code* code);
+  void ExtractJSGlobalPropertyCellReferences(int entry,
+                                             JSGlobalPropertyCell* cell);
+  void ExtractClosureReferences(JSObject* js_obj, int entry);
+  void ExtractPropertyReferences(JSObject* js_obj, int entry);
+  void ExtractElementReferences(JSObject* js_obj, int entry);
+  void ExtractInternalReferences(JSObject* js_obj, int entry);
+  bool IsEssentialObject(Object* object);
   void SetClosureReference(HeapObject* parent_obj,
-                           HeapEntry* parent,
+                           int parent,
                            String* reference_name,
                            Object* child);
   void SetNativeBindReference(HeapObject* parent_obj,
-                              HeapEntry* parent,
+                              int parent,
                               const char* reference_name,
                               Object* child);
   void SetElementReference(HeapObject* parent_obj,
-                           HeapEntry* parent,
+                           int parent,
                            int index,
                            Object* child);
   void SetInternalReference(HeapObject* parent_obj,
-                            HeapEntry* parent,
+                            int parent,
                             const char* reference_name,
                             Object* child,
                             int field_offset = -1);
   void SetInternalReference(HeapObject* parent_obj,
-                            HeapEntry* parent,
+                            int parent,
                             int index,
                             Object* child,
                             int field_offset = -1);
   void SetHiddenReference(HeapObject* parent_obj,
-                          HeapEntry* parent,
+                          int parent,
                           int index,
                           Object* child);
   void SetWeakReference(HeapObject* parent_obj,
-                        HeapEntry* parent_entry,
+                        int parent,
                         int index,
                         Object* child_obj,
                         int field_offset);
   void SetPropertyReference(HeapObject* parent_obj,
-                            HeapEntry* parent,
+                            int parent,
                             String* reference_name,
                             Object* child,
                             const char* name_format_string = NULL,
                             int field_offset = -1);
   void SetPropertyShortcutReference(HeapObject* parent_obj,
-                                    HeapEntry* parent,
+                                    int parent,
                                     String* reference_name,
                                     Object* child);
-  void SetRootShortcutReference(Object* child);
+  void SetUserGlobalReference(Object* user_global);
   void SetRootGcRootsReference();
   void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
   void SetGcSubrootReference(
       VisitorSynchronization::SyncTag tag, bool is_weak, Object* child);
-  void SetObjectName(HeapObject* object);
+  const char* GetStrongGcSubrootName(Object* object);
   void TagObject(Object* obj, const char* tag);
 
   HeapEntry* GetEntry(Object* obj);
@@ -1003,6 +980,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
   SnapshottingProgressReportingInterface* progress_;
   SnapshotFillerInterface* filler_;
   HeapObjectsSet objects_tags_;
+  HeapObjectsSet strong_gc_subroot_names_;
 
   static HeapObject* const kGcRootsObject;
   static HeapObject* const kFirstGcSubrootObject;
@@ -1086,9 +1064,10 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
   bool BuildDominatorTree(const Vector<HeapEntry*>& entries,
                           Vector<int>* dominators);
   bool CalculateRetainedSizes();
-  bool CountEntriesAndReferences();
   bool FillReferences();
-  void FillReversePostorderIndexes(Vector<HeapEntry*>* entries);
+  void FillPostorderIndexes(Vector<HeapEntry*>* entries);
+  bool IsUserGlobalReference(const HeapGraphEdge* edge);
+  void MarkUserReachableObjects();
   void ProgressStep();
   bool ProgressReport(bool force = false);
   bool SetEntriesDominators();
@@ -1113,7 +1092,6 @@ class HeapSnapshotJSONSerializer {
  public:
   explicit HeapSnapshotJSONSerializer(HeapSnapshot* snapshot)
       : snapshot_(snapshot),
-        nodes_(ObjectsMatch),
         strings_(ObjectsMatch),
         next_node_id_(1),
         next_string_id_(1),
@@ -1132,23 +1110,23 @@ class HeapSnapshotJSONSerializer {
         v8::internal::kZeroHashSeed);
   }
 
-  void EnumerateNodes();
   HeapSnapshot* CreateFakeSnapshot();
-  int GetNodeId(HeapEntry* entry);
   int GetStringId(const char* s);
-  void SerializeEdge(HeapGraphEdge* edge);
+  int entry_index(HeapEntry* e) { return e->index() * kNodeFieldsCount; }
+  void SerializeEdge(HeapGraphEdge* edge, bool first_edge);
+  void SerializeEdges(const List<HeapEntry>& nodes);
   void SerializeImpl();
-  void SerializeNode(HeapEntry* entry);
-  void SerializeNodes();
+  void SerializeNode(HeapEntry* entry, int edges_index);
+  void SerializeNodes(const List<HeapEntry>& nodes);
   void SerializeSnapshot();
   void SerializeString(const unsigned char* s);
   void SerializeStrings();
   void SortHashMap(HashMap* map, List<HashMap::Entry*>* sorted_entries);
 
-  static const int kMaxSerializableSnapshotRawSize;
+  static const int kEdgeFieldsCount;
+  static const int kNodeFieldsCount;
 
   HeapSnapshot* snapshot_;
-  HashMap nodes_;
   HashMap strings_;
   int next_node_id_;
   int next_string_id_;
index 04f78b2..ba5e3c8 100644 (file)
@@ -214,13 +214,6 @@ 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;
index f2a4e85..a767ec0 100644 (file)
@@ -62,6 +62,16 @@ 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()) {
index 322efa1..aa67919 100644 (file)
@@ -352,6 +352,42 @@ 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);
index 262ead2..25cb68d 100644 (file)
@@ -93,6 +93,13 @@ 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);
@@ -114,6 +121,7 @@ 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();
index f843278..b7aeac4 100644 (file)
@@ -198,24 +198,55 @@ 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) {
-  PrintF(" CheckCharacterLT(c='u%04x', label[%08x]);\n",
-         limit, LabelToInt(on_less));
+  PrintablePrinter printable(limit);
+  PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
+         limit,
+         *printable,
+         LabelToInt(on_less));
   assembler_->CheckCharacterLT(limit, on_less);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
                                                   Label* on_greater) {
-  PrintF(" CheckCharacterGT(c='u%04x', label[%08x]);\n",
-         limit, LabelToInt(on_greater));
+  PrintablePrinter printable(limit);
+  PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
+         limit,
+         *printable,
+         LabelToInt(on_greater));
   assembler_->CheckCharacterGT(limit, on_greater);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
-  PrintF(" CheckCharacter(c='u%04x', label[%08x]);\n",
-         c, LabelToInt(on_equal));
+  PrintablePrinter printable(c);
+  PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
+         c,
+         *printable,
+         LabelToInt(on_equal));
   assembler_->CheckCharacter(c, on_equal);
 }
 
@@ -234,8 +265,11 @@ void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
 
 void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c,
                                                    Label* on_not_equal) {
-  PrintF(" CheckNotCharacter(c='u%04x', label[%08x]);\n",
-         c, LabelToInt(on_not_equal));
+  PrintablePrinter printable(c);
+  PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
+         c,
+         *printable,
+         LabelToInt(on_not_equal));
   assembler_->CheckNotCharacter(c, on_not_equal);
 }
 
@@ -244,8 +278,10 @@ void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd(
     unsigned c,
     unsigned mask,
     Label* on_equal) {
-  PrintF(" CheckCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n",
+  PrintablePrinter printable(c);
+  PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
          c,
+         *printable,
          mask,
          LabelToInt(on_equal));
   assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
@@ -256,8 +292,10 @@ void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
     unsigned c,
     unsigned mask,
     Label* on_not_equal) {
-  PrintF(" CheckNotCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n",
+  PrintablePrinter printable(c);
+  PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
          c,
+         *printable,
          mask,
          LabelToInt(on_not_equal));
   assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
@@ -269,7 +307,7 @@ void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd(
     uc16 minus,
     uc16 mask,
     Label* on_not_equal) {
-  PrintF(" CheckNotCharacterAfterMinusAnd(c='u%04x', minus=%04x, mask=0x%04x, "
+  PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
              "label[%08x]);\n",
          c,
          minus,
@@ -279,6 +317,53 @@ 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,
@@ -314,7 +399,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("u%04x", str[i]);
+    PrintF("0x%04x", str[i]);
   }
   PrintF("\", cp_offset=%d, label[%08x])\n",
          cp_offset, LabelToInt(on_failure));
index 1cf0349..3fd4d8b 100644 (file)
@@ -68,6 +68,13 @@ 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();
index 0314c70..8587435 100644 (file)
@@ -45,6 +45,11 @@ 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,
@@ -106,12 +111,23 @@ class RegExpMacroAssembler {
   virtual void CheckNotCharacterAfterAnd(unsigned c,
                                          unsigned and_with,
                                          Label* on_not_equal) = 0;
-  // Subtract a constant from the current character, then or with the given
+  // Subtract a constant from the current character, then and 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;
index bc9508d..a574f62 100644 (file)
@@ -278,11 +278,7 @@ function TrimRegExp(regexp) {
 
 
 function RegExpToString() {
-  // 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 + '/';
+  var result = '/' + this.source + '/';
   if (this.global) result += 'g';
   if (this.ignoreCase) result += 'i';
   if (this.multiline) result += 'm';
@@ -296,7 +292,7 @@ function RegExpToString() {
 // of the last successful match.
 function RegExpGetLastMatch() {
   if (lastMatchInfoOverride !== null) {
-    return lastMatchInfoOverride[0];
+    return OVERRIDE_MATCH(lastMatchInfoOverride);
   }
   var regExpSubject = LAST_SUBJECT(lastMatchInfo);
   return SubString(regExpSubject,
@@ -334,8 +330,8 @@ function RegExpGetLeftContext() {
     subject = LAST_SUBJECT(lastMatchInfo);
   } else {
     var override = lastMatchInfoOverride;
-    start_index = override[override.length - 2];
-    subject = override[override.length - 1];
+    start_index = OVERRIDE_POS(override);
+    subject = OVERRIDE_SUBJECT(override);
   }
   return SubString(subject, 0, start_index);
 }
@@ -349,8 +345,9 @@ function RegExpGetRightContext() {
     subject = LAST_SUBJECT(lastMatchInfo);
   } else {
     var override = lastMatchInfoOverride;
-    subject = override[override.length - 1];
-    start_index = override[override.length - 2] + subject.length;
+    subject = OVERRIDE_SUBJECT(override);
+    var match = OVERRIDE_MATCH(override);
+    start_index = OVERRIDE_POS(override) + match.length;
   }
   return SubString(subject, start_index, subject.length);
 }
@@ -362,7 +359,9 @@ function RegExpGetRightContext() {
 function RegExpMakeCaptureGetter(n) {
   return function() {
     if (lastMatchInfoOverride) {
-      if (n < lastMatchInfoOverride.length - 2) return lastMatchInfoOverride[n];
+      if (n < lastMatchInfoOverride.length - 2) {
+        return OVERRIDE_CAPTURE(lastMatchInfoOverride, n);
+      }
       return '';
     }
     var index = n * 2;
index 55f93ee..e58ddb4 100644 (file)
@@ -111,7 +111,7 @@ void Processor::VisitBlock(Block* node) {
 
 void Processor::VisitExpressionStatement(ExpressionStatement* node) {
   // Rewrite : <x>; -> .result = <x>;
-  if (!is_set_) {
+  if (!is_set_ && !node->expression()->IsThrow()) {
     node->set_expression(SetResult(node->expression()));
     if (!in_try_) is_set_ = true;
   }
index 6ed4ff4..568e48e 100644 (file)
@@ -65,6 +65,12 @@ static const int kSizeLimit = 1500;
 // Number of times a function has to be seen on the stack before it is
 // optimized.
 static const int kProfilerTicksBeforeOptimization = 2;
+// If a function does not have enough type info (according to
+// FLAG_type_info_threshold), but has seen a huge number of ticks,
+// optimize it as it is.
+static const int kTicksWhenNotEnoughTypeInfo = 100;
+// We only have one byte to store the number of ticks.
+STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);
 
 // Maximum size in bytes of generated code for a function to be optimized
 // the very first time it is seen on the stack.
@@ -88,12 +94,14 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
       sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit),
       sampler_ticks_until_threshold_adjustment_(
           kSamplerTicksBetweenThresholdAdjustment),
-      sampler_window_position_(0) {
+      sampler_window_position_(0),
+      any_ic_changed_(false),
+      code_generated_(false) {
   ClearSampleBuffer();
 }
 
 
-void RuntimeProfiler::GlobalSetup() {
+void RuntimeProfiler::GlobalSetUp() {
   ASSERT(!has_been_globally_set_up_);
   enabled_ = V8::UseCrankshaft() && FLAG_opt;
 #ifdef DEBUG
@@ -103,20 +111,20 @@ void RuntimeProfiler::GlobalSetup() {
 
 
 static void GetICCounts(JSFunction* function,
-                        int* ic_with_typeinfo_count,
+                        int* ic_with_type_info_count,
                         int* ic_total_count,
                         int* percentage) {
   *ic_total_count = 0;
-  *ic_with_typeinfo_count = 0;
+  *ic_with_type_info_count = 0;
   Object* raw_info =
       function->shared()->code()->type_feedback_info();
   if (raw_info->IsTypeFeedbackInfo()) {
     TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
-    *ic_with_typeinfo_count = info->ic_with_typeinfo_count();
+    *ic_with_type_info_count = info->ic_with_type_info_count();
     *ic_total_count = info->ic_total_count();
   }
   *percentage = *ic_total_count > 0
-      ? 100 * *ic_with_typeinfo_count / *ic_total_count
+      ? 100 * *ic_with_type_info_count / *ic_total_count
       : 100;
 }
 
@@ -173,14 +181,10 @@ 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);
@@ -259,13 +263,14 @@ void RuntimeProfiler::OptimizeNow() {
       }
     }
 
-    if (function->IsMarkedForLazyRecompilation() &&
-        function->shared()->code()->kind() == Code::FUNCTION) {
-      Code* unoptimized = function->shared()->code();
-      int nesting = unoptimized->allow_osr_at_loop_nesting_level();
+    Code* shared_code = function->shared()->code();
+    if (shared_code->kind() != Code::FUNCTION) continue;
+
+    if (function->IsMarkedForLazyRecompilation()) {
+      int nesting = shared_code->allow_osr_at_loop_nesting_level();
       if (nesting == 0) AttemptOnStackReplacement(function);
       int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker);
-      unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting);
+      shared_code->set_allow_osr_at_loop_nesting_level(new_nesting);
     }
 
     // Do not record non-optimizable functions.
@@ -283,7 +288,7 @@ void RuntimeProfiler::OptimizeNow() {
     }
 
     if (FLAG_watch_ic_patching) {
-      int ticks = function->shared()->profiler_ticks();
+      int ticks = shared_code->profiler_ticks();
 
       if (ticks >= kProfilerTicksBeforeOptimization) {
         int typeinfo, total, percentage;
@@ -292,12 +297,10 @@ void RuntimeProfiler::OptimizeNow() {
           // If this particular function hasn't had any ICs patched for enough
           // ticks, optimize it now.
           Optimize(function, "hot and stable");
-        } else if (ticks >= 100) {
-          // If this function does not have enough type info, but has
-          // seen a huge number of ticks, optimize it as it is.
+        } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
           Optimize(function, "not much type info but very hot");
         } else {
-          function->shared()->set_profiler_ticks(ticks + 1);
+          shared_code->set_profiler_ticks(ticks + 1);
           if (FLAG_trace_opt_verbose) {
             PrintF("[not yet optimizing ");
             function->PrintName();
@@ -306,20 +309,12 @@ void RuntimeProfiler::OptimizeNow() {
           }
         }
       } else if (!any_ic_changed_ &&
-          function->shared()->code()->instruction_size() < kMaxSizeEarlyOpt) {
+          shared_code->instruction_size() < kMaxSizeEarlyOpt) {
         // 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 {
-        function->shared()->set_profiler_ticks(ticks + 1);
+        shared_code->set_profiler_ticks(ticks + 1);
       }
     } else {  // !FLAG_watch_ic_patching
       samples[sample_count++] = function;
@@ -338,7 +333,6 @@ 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
@@ -351,11 +345,7 @@ 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();
 }
 
@@ -372,9 +362,7 @@ void RuntimeProfiler::SetUp() {
 
 
 void RuntimeProfiler::Reset() {
-  if (FLAG_watch_ic_patching) {
-    total_code_generated_ = 0;
-  } else {  // !FLAG_watch_ic_patching
+  if (!FLAG_watch_ic_patching) {
     sampler_threshold_ = kSamplerThresholdInit;
     sampler_threshold_size_factor_ = kSamplerThresholdSizeFactorInit;
     sampler_ticks_until_threshold_adjustment_ =
index e338849..ab6cb37 100644 (file)
@@ -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,13 +63,6 @@ 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.
@@ -130,7 +123,6 @@ 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
index 320ab59..0b80eff 100644 (file)
@@ -1289,90 +1289,79 @@ 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_const_property = value->IsTheHole();
-    bool is_function_declaration = false;
-    if (value->IsUndefined() || is_const_property) {
+    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) {
       // 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);
-      global->Lookup(*name, &lookup);
+      if (FLAG_es52_globals)
+        global->LocalLookup(*name, &lookup);
+      else
+        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 {
-      is_function_declaration = true;
+    } else if (is_function) {
       // 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, 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.
+    // Compute the property attributes. According to ECMA-262,
+    // the property must be non-configurable except in eval.
     int attr = NONE;
-    if (!DeclareGlobalsEvalFlag::decode(flags)) {
+    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
+    if (!is_eval || is_module) {
       attr |= DONT_DELETE;
     }
     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
-    if (is_const_property || (is_native && is_function_declaration)) {
+    if (is_const || is_module || (is_native && is_function)) {
       attr |= READ_ONLY;
     }
 
     LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
 
-    // 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 (!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);
         }
-        // Do not change DONT_DELETE to false from true.
-        attr |= lookup.GetAttributes() & DONT_DELETE;
+        // If the existing property is not configurable, keep its attributes.
+        attr = lookup.GetAttributes();
       }
-      PropertyAttributes attributes = static_cast<PropertyAttributes>(attr);
-
-      RETURN_IF_EMPTY_HANDLE(
-          isolate,
-          JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
-                                                     attributes));
+      // Define or redefine own property.
+      RETURN_IF_EMPTY_HANDLE(isolate,
+          JSObject::SetLocalPropertyIgnoreAttributes(
+              global, name, value, static_cast<PropertyAttributes>(attr)));
     } else {
-      RETURN_IF_EMPTY_HANDLE(
-          isolate,
-          JSReceiver::SetProperty(global, name, value,
-                                  static_cast<PropertyAttributes>(attr),
-                                  language_mode == CLASSIC_MODE
-                                      ? kNonStrictMode : kStrictMode));
+      // 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));
     }
   }
 
@@ -1405,6 +1394,8 @@ 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());
@@ -1467,9 +1458,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
         return ThrowRedeclarationError(isolate, "const", name);
       }
     }
-    RETURN_IF_EMPTY_HANDLE(
-        isolate,
-        JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
+    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 isolate->heap()->undefined_value();
@@ -1787,6 +1783,9 @@ 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();
@@ -2101,7 +2100,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),
@@ -2886,12 +2885,79 @@ 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* StringReplaceStringWithString(
+MUST_USE_RESULT static MaybeObject* StringReplaceAtomRegExpWithString(
     Isolate* isolate,
     Handle<String> subject,
     Handle<JSRegExp> pattern_regexp,
-    Handle<String> replacement) {
+    Handle<String> replacement,
+    Handle<JSArray> last_match_info) {
   ASSERT(subject->IsFlat());
   ASSERT(replacement->IsFlat());
 
@@ -2950,6 +3016,12 @@ MUST_USE_RESULT static MaybeObject* StringReplaceStringWithString(
                         subject_pos,
                         subject_len);
   }
+
+  SetLastMatchInfoNoCaptures(subject,
+                             last_match_info,
+                             indices.at(matches - 1),
+                             indices.at(matches - 1) + pattern_len);
+
   return *result;
 }
 
@@ -2998,11 +3070,19 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
       compiled_replacement.simple_hint()) {
     if (subject_handle->HasOnlyAsciiChars() &&
         replacement_handle->HasOnlyAsciiChars()) {
-      return StringReplaceStringWithString<SeqAsciiString>(
-          isolate, subject_handle, regexp_handle, replacement_handle);
+      return StringReplaceAtomRegExpWithString<SeqAsciiString>(
+          isolate,
+          subject_handle,
+          regexp_handle,
+          replacement_handle,
+          last_match_info_handle);
     } else {
-      return StringReplaceStringWithString<SeqTwoByteString>(
-          isolate, subject_handle, regexp_handle, replacement_handle);
+      return StringReplaceAtomRegExpWithString<SeqTwoByteString>(
+          isolate,
+          subject_handle,
+          regexp_handle,
+          replacement_handle,
+          last_match_info_handle);
     }
   }
 
@@ -3091,21 +3171,29 @@ 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 StringReplaceStringWithString<SeqAsciiString>(
-          isolate, subject_handle, regexp_handle, empty_string_handle);
+      return StringReplaceAtomRegExpWithString<SeqAsciiString>(
+          isolate,
+          subject_handle,
+          regexp_handle,
+          empty_string_handle,
+          last_match_info_handle);
     } else {
-      return StringReplaceStringWithString<SeqTwoByteString>(
-          isolate, subject_handle, regexp_handle, empty_string_handle);
+      return StringReplaceAtomRegExpWithString<SeqTwoByteString>(
+          isolate,
+          subject_handle,
+          regexp_handle,
+          empty_string_handle,
+          last_match_info_handle);
     }
   }
 
-  Handle<JSArray> last_match_info_handle(last_match_info);
   Handle<Object> match = RegExpImpl::Exec(regexp_handle,
                                           subject_handle,
                                           0,
@@ -3125,6 +3213,10 @@ 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) {
@@ -3140,7 +3232,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
   }
 
   // If the regexp isn't global, only match once.
-  if (!regexp_handle->GetFlags().is_global()) {
+  if (!global) {
     if (start > 0) {
       String::WriteToFlat(*subject_handle,
                           answer->GetChars(),
@@ -3639,70 +3731,6 @@ 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,
@@ -3842,6 +3870,8 @@ 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,
@@ -3870,10 +3900,6 @@ 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];
@@ -3926,11 +3952,6 @@ 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;
@@ -3962,12 +3983,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;
     }
   }
@@ -3976,6 +3997,9 @@ 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);
@@ -4669,7 +4693,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   HandleScope scope;
 
   Object* raw_boilerplate_object = literals->get(literal_index);
-  Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object));
+  Handle<JSArray> boilerplate(JSArray::cast(raw_boilerplate_object));
 #if DEBUG
   ElementsKind elements_kind = object->GetElementsKind();
 #endif
@@ -4680,25 +4704,59 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   if (value->IsNumber()) {
     ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS);
     JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
-    JSObject::TransitionElementsKind(boilerplate_object, FAST_DOUBLE_ELEMENTS);
+    if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(),
+                                            FAST_DOUBLE_ELEMENTS)) {
+      JSObject::TransitionElementsKind(boilerplate, 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);
-    JSObject::TransitionElementsKind(boilerplate_object, FAST_ELEMENTS);
-    FixedArray* object_array =
-        FixedArray::cast(object->elements());
+    if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(),
+                                            FAST_ELEMENTS)) {
+      JSObject::TransitionElementsKind(boilerplate, 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) {
@@ -7582,7 +7640,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
     }
   }
   date->SetValue(value, is_value_nan);
-  return *date;
+  return value;
 }
 
 
@@ -8043,8 +8101,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
   ASSERT(args.length() == 1);
   Handle<JSFunction> function = args.at<JSFunction>(0);
 
-  function->shared()->set_profiler_ticks(0);
-
   // If the function is not compiled ignore the lazy
   // recompilation. This can happen if the debugger is activated and
   // the function is returned to the not compiled state.
@@ -8067,6 +8123,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) {
     function->ReplaceCode(function->shared()->code());
     return function->code();
   }
+  function->shared()->code()->set_profiler_ticks(0);
   if (JSFunction::CompileOptimized(function,
                                    AstNode::kNoNumber,
                                    CLEAR_EXCEPTION)) {
@@ -8123,6 +8180,14 @@ 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");
+      }
     }
   }
 }
@@ -8212,6 +8277,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearFunctionTypeFeedback) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  Code* unoptimized = function->shared()->code();
+  if (unoptimized->kind() == Code::FUNCTION) {
+    unoptimized->ClearInlineCaches();
+    unoptimized->ClearTypeFeedbackCells(isolate->heap());
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
 #if defined(USE_SIMULATOR)
   return isolate->heap()->true_value();
@@ -8251,10 +8329,13 @@ 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) {
-    return Smi::FromInt(3);  // 3 == "always".
+    // 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".
   }
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
                                  : Smi::FromInt(2);  // 2 == "no".
 }
@@ -8358,14 +8439,10 @@ 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();
@@ -8399,6 +8476,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
+  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
+  return isolate->heap()->nan_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
   HandleScope scope(isolate);
   ASSERT(args.length() >= 2);
@@ -8598,6 +8681,25 @@ 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);
@@ -10929,10 +11031,10 @@ static Handle<JSObject> MaterializeModuleScope(
 }
 
 
-// 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.
+// 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.
 class ScopeIterator {
  public:
   enum ScopeType {
@@ -11033,6 +11135,18 @@ 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(); }
 
@@ -11253,6 +11367,22 @@ 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
@@ -11290,18 +11420,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
   if (it.Done()) {
     return isolate->heap()->undefined_value();
   }
+  return MaterializeScopeDetails(isolate, &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);
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
 
-  return *isolate->factory()->NewJSArrayWithElements(details);
+  // 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);
+}
+
+
+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();
+  }
+
+  return MaterializeScopeDetails(isolate, &it);
 }
 
 
index fe9cfd9..a09d9cc 100644 (file)
@@ -77,6 +77,7 @@ namespace internal {
   \
   /* Utilities */ \
   F(CheckIsBootstrapping, 0, 1) \
+  F(GetRootNaN, 0, 1) \
   F(Call, -1 /* >= 2 */, 1) \
   F(Apply, 5, 1) \
   F(GetFunctionDelegate, 1, 1) \
@@ -88,6 +89,7 @@ namespace internal {
   F(NotifyDeoptimized, 1, 1) \
   F(NotifyOSR, 0, 1) \
   F(DeoptimizeFunction, 1, 1) \
+  F(ClearFunctionTypeFeedback, 1, 1) \
   F(RunningInSimulator, 0, 1) \
   F(OptimizeFunctionOnNextCall, -1, 1) \
   F(GetOptimizationStatus, 1, 1) \
@@ -97,6 +99,8 @@ 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) \
@@ -323,6 +327,7 @@ 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) \
@@ -400,6 +405,8 @@ 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) \
index 53d9a39..6b48734 100644 (file)
@@ -47,7 +47,7 @@ var $String = global.String;
 var $Number = global.Number;
 var $Function = global.Function;
 var $Boolean = global.Boolean;
-var $NaN = 0/0;
+var $NaN = %GetRootNaN();
 var builtins = this;
 
 // ECMA-262 Section 11.9.3.
index 7901b5d..f24af2e 100755 (executable)
@@ -611,7 +611,7 @@ void Scanner::SeekForward(int pos) {
 }
 
 
-void Scanner::ScanEscape() {
+bool Scanner::ScanEscape() {
   uc32 c = c0_;
   Advance();
 
@@ -621,7 +621,7 @@ void Scanner::ScanEscape() {
     if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
     // Allow LF+CR newlines in multiline string literals.
     if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance();
-    return;
+    return true;
   }
 
   switch (c) {
@@ -635,13 +635,13 @@ void Scanner::ScanEscape() {
     case 't' : c = '\t'; break;
     case 'u' : {
       c = ScanHexNumber(4);
-      if (c < 0) c = 'u';
+      if (c < 0) return false;
       break;
     }
     case 'v' : c = '\v'; break;
     case 'x' : {
       c = ScanHexNumber(2);
-      if (c < 0) c = 'x';
+      if (c < 0) return false;
       break;
     }
     case '0' :  // fall through
@@ -654,10 +654,11 @@ void Scanner::ScanEscape() {
     case '7' : c = ScanOctalEscape(c, 2); break;
   }
 
-  // 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.
+  // 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.
   AddLiteralChar(c);
+  return true;
 }
 
 
@@ -696,8 +697,7 @@ Token::Value Scanner::ScanString() {
     uc32 c = c0_;
     Advance();
     if (c == '\\') {
-      if (c0_ < 0) return Token::ILLEGAL;
-      ScanEscape();
+      if (c0_ < 0 || !ScanEscape()) return Token::ILLEGAL;
     } else {
       AddLiteralChar(c);
     }
index 045e7d2..4de413b 100644 (file)
@@ -520,13 +520,16 @@ class Scanner {
   Token::Value ScanIdentifierOrKeyword();
   Token::Value ScanIdentifierSuffix(LiteralScope* literal);
 
-  void ScanEscape();
   Token::Value ScanString();
 
-  // Decodes a unicode escape-sequence which is part of an identifier.
+  // 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.
   // If the escape sequence cannot be decoded the result is kBadChar.
   uc32 ScanIdentifierUnicodeEscape();
-  // Recognizes a uniocde escape-sequence and adds its characters,
+  // Scans a Unicode escape-sequence and adds its characters,
   // uninterpreted, to the current literal. Used for parsing RegExp
   // flags.
   bool ScanLiteralUnicodeEscape();
index 0f36234..f50af30 100644 (file)
@@ -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()->var();
+    Variable* var = scope->function()->proxy()->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()->var()->index();
-    scope_info->set(index++, *scope->function()->name());
+    int var_index = scope->function()->proxy()->var()->index();
+    scope_info->set(index++, *scope->function()->proxy()->name());
     scope_info->set(index++, Smi::FromInt(var_index));
     ASSERT(function_name_info != STACK ||
            (var_index == scope_info->StackLocalCount() &&
@@ -142,7 +142,9 @@ 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());
+  ASSERT(scope->num_heap_slots() == scope_info->ContextLength() ||
+         (scope->num_heap_slots() == kVariablePartIndex &&
+          scope_info->ContextLength() == 0));
   return scope_info;
 }
 
index 859cbd1..6f6032a 100644 (file)
@@ -388,14 +388,17 @@ 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 =
@@ -405,21 +408,27 @@ Variable* Scope::LocalLookup(Handle<String> name) {
                          true,
                          Variable::NORMAL,
                          init_flag);
-  var->AllocateTo(Variable::CONTEXT, index);
+  var->AllocateTo(location, index);
   return var;
 }
 
 
 Variable* Scope::LookupFunctionVar(Handle<String> name,
                                    AstNodeFactory<AstNullVisitor>* factory) {
-  if (function_ != NULL && function_->name().is_identical_to(name)) {
-    return function_->var();
+  if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) {
+    return function_->proxy()->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 = DeclareFunctionVar(name, mode, factory);
+    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);
     var->AllocateTo(Variable::CONTEXT, index);
     return var;
   } else {
@@ -791,7 +800,7 @@ void Scope::Print(int n) {
   // Function name, if any (named function literals, only).
   if (function_ != NULL) {
     Indent(n1, "// (local) function name: ");
-    PrintName(function_->name());
+    PrintName(function_->proxy()->name());
     PrintF("\n");
   }
 
@@ -824,7 +833,7 @@ void Scope::Print(int n) {
   // Print locals.
   Indent(n1, "// function var\n");
   if (function_ != NULL) {
-    PrintVar(n1, function_->var());
+    PrintVar(n1, function_->proxy()->var());
   }
 
   Indent(n1, "// temporary vars\n");
@@ -949,10 +958,14 @@ bool Scope::ResolveVariable(CompilationInfo* info,
       break;
 
     case BOUND_EVAL_SHADOWED:
-      // We found a variable variable binding that might be shadowed
-      // by 'eval' introduced variable bindings.
+      // 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).
       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);
@@ -1086,7 +1099,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()) return true;
+  if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
   return var->has_forced_context_allocation() ||
       scope_calls_eval_ ||
       inner_scope_calls_eval_ ||
@@ -1204,7 +1217,7 @@ void Scope::AllocateNonParameterLocals() {
   // because of the current ScopeInfo implementation (see
   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
   if (function_ != NULL) {
-    AllocateNonParameterLocal(function_->var());
+    AllocateNonParameterLocal(function_->proxy()->var());
   }
 }
 
@@ -1230,7 +1243,8 @@ 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.
-  bool must_have_context = is_with_scope() ||
+  // Likewise for modules.
+  bool must_have_context = is_with_scope() || is_module_scope() ||
       (is_function_scope() && calls_eval());
 
   // If we didn't allocate any locals in the local context, then we only
@@ -1246,14 +1260,14 @@ void Scope::AllocateVariablesRecursively() {
 
 int Scope::StackLocalCount() const {
   return num_stack_slots() -
-      (function_ != NULL && function_->var()->IsStackLocal() ? 1 : 0);
+      (function_ != NULL && function_->proxy()->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_->var()->IsContextSlot() ? 1 : 0);
+      (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
 }
 
 } }  // namespace v8::internal
index d315b7e..e1a658a 100644 (file)
@@ -126,15 +126,9 @@ 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.
-  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;
+  void DeclareFunctionVar(VariableDeclaration* declaration) {
+    ASSERT(is_function_scope());
+    function_ = declaration;
   }
 
   // Declare a parameter in this scope.  When there are duplicated
@@ -312,9 +306,8 @@ 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.
-  VariableProxy* function() const {
+  // literals, or NULL.  Only valid for function scopes.
+  VariableDeclaration* function() const {
     ASSERT(is_function_scope());
     return function_;
   }
@@ -446,7 +439,7 @@ class Scope: public ZoneObject {
   // Convenience variable.
   Variable* receiver_;
   // Function variable, if any; function scopes only.
-  VariableProxy* function_;
+  VariableDeclaration* function_;
   // Convenience variable; function scopes only.
   Variable* arguments_;
   // Interface; module scopes only.
index 01d5f1c..cf8e5e1 100644 (file)
@@ -244,7 +244,7 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
     "Isolate::" #hacker_name "_address",
     FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL)
     NULL
-#undef C
+#undef BUILD_NAME_LITERAL
   };
 
   for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) {
index 6c5ce89..75fea06 100644 (file)
@@ -69,6 +69,12 @@ class SmallPointerList {
     data_ = kEmptyTag;
   }
 
+  void Sort() {
+    if ((data_ & kTagMask) == kListTag) {
+      list()->Sort(compare_value);
+    }
+  }
+
   bool is_empty() const { return length() == 0; }
 
   int length() const {
@@ -159,6 +165,10 @@ 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;
index 3709009..ed78fc7 100644 (file)
@@ -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,11 +295,27 @@ 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(allocation_info_.top);
+  Object* obj = HeapObject::FromAddress(old_top);
   allocation_info_.top += size_in_bytes;
   ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
 
index defe352..a0c8f2c 100644 (file)
@@ -362,15 +362,22 @@ Address MemoryAllocator::AllocateAlignedMemory(size_t size,
   if (base == NULL) return NULL;
 
   if (executable == EXECUTABLE) {
-    CommitCodePage(&reservation, base, size);
+    if (!CommitCodePage(&reservation, base, size)) {
+      base = NULL;
+    }
   } else {
-    if (!reservation.Commit(base,
-                            size,
-                            executable == EXECUTABLE)) {
-      return NULL;
+    if (!reservation.Commit(base, size, false)) {
+      base = NULL;
     }
   }
 
+  if (base == NULL) {
+    // Failed to commit the body. Release the mapping and any partially
+    // commited regions inside it.
+    reservation.Release();
+    return NULL;
+  }
+
   controller->TakeControl(&reservation);
   return base;
 }
@@ -565,11 +572,10 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
 }
 
 
-Page* MemoryAllocator::AllocatePage(PagedSpace* owner,
+Page* MemoryAllocator::AllocatePage(intptr_t size,
+                                    PagedSpace* owner,
                                     Executability executable) {
-  MemoryChunk* chunk = AllocateChunk(owner->AreaSize(),
-                                     executable,
-                                     owner);
+  MemoryChunk* chunk = AllocateChunk(size, executable, owner);
 
   if (chunk == NULL) return NULL;
 
@@ -578,8 +584,8 @@ Page* MemoryAllocator::AllocatePage(PagedSpace* owner,
 
 
 LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size,
-                                              Executability executable,
-                                              Space* owner) {
+                                              Space* owner,
+                                              Executability executable) {
   MemoryChunk* chunk = AllocateChunk(object_size, executable, owner);
   if (chunk == NULL) return NULL;
   return LargePage::Initialize(isolate_->heap(), chunk);
@@ -833,7 +839,6 @@ MaybeObject* PagedSpace::FindObject(Address addr) {
 
 bool PagedSpace::CanExpand() {
   ASSERT(max_capacity_ % AreaSize() == 0);
-  ASSERT(Capacity() % AreaSize() == 0);
 
   if (Capacity() == max_capacity_) return false;
 
@@ -848,8 +853,14 @@ bool PagedSpace::CanExpand() {
 bool PagedSpace::Expand() {
   if (!CanExpand()) return false;
 
-  Page* p = heap()->isolate()->memory_allocator()->
-      AllocatePage(this, executable());
+  intptr_t size = AreaSize();
+
+  if (anchor_.next_page() == &anchor_) {
+    size = SizeOfFirstPage();
+  }
+
+  Page* p = heap()->isolate()->memory_allocator()->AllocatePage(
+      size, this, executable());
   if (p == NULL) return false;
 
   ASSERT(Capacity() <= max_capacity_);
@@ -860,6 +871,38 @@ 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;
@@ -903,7 +946,6 @@ void PagedSpace::ReleasePage(Page* page) {
   }
 
   ASSERT(Capacity() > 0);
-  ASSERT(Capacity() % AreaSize() == 0);
   accounting_stats_.ShrinkSpace(AreaSize());
 }
 
@@ -1042,6 +1084,7 @@ 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);
@@ -1198,13 +1241,15 @@ MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) {
         allocation_info_.limit + inline_allocation_limit_step_,
         high);
     int bytes_allocated = static_cast<int>(new_top - top_on_previous_step_);
-    heap()->incremental_marking()->Step(bytes_allocated);
+    heap()->incremental_marking()->Step(
+        bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD);
     top_on_previous_step_ = new_top;
     return AllocateRaw(size_in_bytes);
   } else if (AddFreshPage()) {
     // Switched to new page. Try allocating again.
     int bytes_allocated = static_cast<int>(old_top - top_on_previous_step_);
-    heap()->incremental_marking()->Step(bytes_allocated);
+    heap()->incremental_marking()->Step(
+        bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD);
     top_on_previous_step_ = to_space_.page_low();
     return AllocateRaw(size_in_bytes);
   } else {
@@ -2250,8 +2295,6 @@ bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) {
     first_unswept_page_ = p;
   }
 
-  heap()->LowerOldGenLimits(freed_bytes);
-
   heap()->FreeQueuedChunks();
 
   return IsSweepingComplete();
@@ -2581,7 +2624,7 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size,
   }
 
   LargePage* page = heap()->isolate()->memory_allocator()->
-      AllocateLargePage(object_size, executable, this);
+      AllocateLargePage(object_size, this, executable);
   if (page == NULL) return Failure::RetryAfterGC(identity());
   ASSERT(page->area_size() >= object_size);
 
index b614c3b..b0ecc5d 100644 (file)
@@ -637,8 +637,10 @@ 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.
 //
@@ -950,11 +952,11 @@ class MemoryAllocator {
 
   void TearDown();
 
-  Page* AllocatePage(PagedSpace* owner, Executability executable);
+  Page* AllocatePage(
+      intptr_t size, PagedSpace* owner, Executability executable);
 
-  LargePage* AllocateLargePage(intptr_t object_size,
-                                      Executability executable,
-                                      Space* owner);
+  LargePage* AllocateLargePage(
+      intptr_t object_size, Space* owner, Executability executable);
 
   void Free(MemoryChunk* chunk);
 
@@ -1040,7 +1042,9 @@ class MemoryAllocator {
     return CodePageAreaEndOffset() - CodePageAreaStartOffset();
   }
 
-  static bool CommitCodePage(VirtualMemory* vm, Address start, size_t size);
+  MUST_USE_RESULT static bool CommitCodePage(VirtualMemory* vm,
+                                             Address start,
+                                             size_t size);
 
  private:
   Isolate* isolate_;
@@ -1518,6 +1522,10 @@ 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 ||
@@ -1625,6 +1633,8 @@ class PagedSpace : public Space {
   // Maximum capacity of this space.
   intptr_t max_capacity_;
 
+  intptr_t SizeOfFirstPage();
+
   // Accounting information for this space.
   AllocationStats accounting_stats_;
 
@@ -2367,11 +2377,6 @@ 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_;
index 84dde3d..6115930 100644 (file)
@@ -189,7 +189,9 @@ 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.
-    return %StringMatch(subject, regexp, lastMatchInfo);
+    var result = %StringMatch(subject, regexp, lastMatchInfo);
+    if (result !== null) lastMatchInfoOverride = null;
+    return result;
   }
   // Non-regexp argument.
   regexp = new $RegExp(regexp);
@@ -235,10 +237,28 @@ function StringReplace(search, replace) {
                                                         replace);
       }
     } else {
-      return %StringReplaceRegExpWithString(subject,
-                                            search,
-                                            TO_STRING_INLINE(replace),
-                                            lastMatchInfo);
+      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;
+      }
     }
   }
 
@@ -257,47 +277,34 @@ function StringReplace(search, replace) {
   if (start < 0) return subject;
   var end = start + search.length;
 
-  var builder = new ReplaceResultBuilder(subject);
-  // prefix
-  builder.addSpecialSlice(0, start);
+  var result = SubString(subject, 0, start);
 
   // Compute the string to replace with.
   if (IS_SPEC_FUNCTION(replace)) {
     var receiver = %GetDefaultReceiver(replace);
-    builder.add(%_CallFunction(receiver,
-                               search,
-                               start,
-                               subject,
-                               replace));
+    result += %_CallFunction(receiver, search, start, subject, replace);
   } else {
     reusableMatchInfo[CAPTURE0] = start;
     reusableMatchInfo[CAPTURE1] = end;
     replace = TO_STRING_INLINE(replace);
-    ExpandReplacement(replace, subject, reusableMatchInfo, builder);
+    result = ExpandReplacement(replace, subject, reusableMatchInfo, result);
   }
 
-  // suffix
-  builder.addSpecialSlice(end, subject.length);
-
-  return builder.generate();
+  return result + SubString(subject, end, subject.length);
 }
 
 
 // Expand the $-expressions in the string and return a new string with
 // the result.
-function ExpandReplacement(string, subject, matchInfo, builder) {
+function ExpandReplacement(string, subject, matchInfo, result) {
   var length = string.length;
-  var builder_elements = builder.elements;
   var next = %StringIndexOf(string, '$', 0);
   if (next < 0) {
-    if (length > 0) builder_elements.push(string);
-    return;
+    if (length > 0) result += string;
+    return result;
   }
 
-  // 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));
+  if (next > 0) result += SubString(string, 0, next);
 
   while (true) {
     var expansion = '$';
@@ -306,51 +313,21 @@ function ExpandReplacement(string, subject, matchInfo, builder) {
       var peek = %_StringCharCodeAt(string, position);
       if (peek == 36) {         // $$
         ++position;
-        builder_elements.push('$');
+        result += '$';
       } else if (peek == 38) {  // $& - match
         ++position;
-        builder.addSpecialSlice(matchInfo[CAPTURE0],
-                                matchInfo[CAPTURE1]);
+        result += SubString(subject, matchInfo[CAPTURE0], matchInfo[CAPTURE1]);
       } else if (peek == 96) {  // $` - prefix
         ++position;
-        builder.addSpecialSlice(0, matchInfo[CAPTURE0]);
+        result += SubString(subject, 0, matchInfo[CAPTURE0]);
       } else if (peek == 39) {  // $' - suffix
         ++position;
-        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;
-        }
+        result += SubString(subject, matchInfo[CAPTURE1], subject.length);
       } else {
-        builder_elements.push('$');
+        result += '$';
       }
     } else {
-      builder_elements.push('$');
+      result += '$';
     }
 
     // Go the the next $ in the string.
@@ -360,16 +337,17 @@ function ExpandReplacement(string, subject, matchInfo, builder) {
     // haven't reached the end, we need to append the suffix.
     if (next < 0) {
       if (position < length) {
-        builder_elements.push(SubString(string, position, length));
+        result += SubString(string, position, length);
       }
-      return;
+      return result;
     }
 
     // Append substring between the previous and the next $ character.
     if (next > position) {
-      builder_elements.push(SubString(string, position, next));
+      result += SubString(string, position, next);
     }
   }
+  return result;
 }
 
 
@@ -386,18 +364,6 @@ 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.
@@ -427,14 +393,22 @@ 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);
-    while (i < len) {
+    for (var i = 0; i < len; i++) {
       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 {
@@ -446,23 +420,25 @@ 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);
-    while (i < len) {
+    for (var i = 0; i < len; i++) {
       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);
@@ -476,9 +452,8 @@ 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];
-  result.addSpecialSlice(0, index);
+  var result = SubString(subject, 0, index);
   var endOfMatch = matchInfo[CAPTURE1];
   // Compute the parameter list consisting of the match, captures, index,
   // and subject for the replace function invocation.
@@ -490,8 +465,7 @@ 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++) {
@@ -503,11 +477,10 @@ function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
     replacement = %Apply(replace, receiver, parameters, 0, j + 2);
   }
 
-  result.add(replacement);  // The add method converts to string if necessary.
+  result += replacement;  // The add method converts to string if necessary.
   // Can't use matchInfo any more from here, since the function could
   // overwrite it.
-  result.addSpecialSlice(endOfMatch, subject.length);
-  return result.generate();
+  return result + SubString(subject, endOfMatch, subject.length);
 }
 
 
index 3371b1b..bd7163a 100644 (file)
@@ -939,7 +939,8 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
 RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
   ASSERT(args[0]->IsJSObject());
   ASSERT(args[1]->IsJSObject());
-  AccessorInfo* callback = AccessorInfo::cast(args[3]);
+  ASSERT(args[3]->IsSmi());
+  AccessorInfo* callback = AccessorInfo::cast(args[4]);
   Address getter_address = v8::ToCData<Address>(callback->getter());
   v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
   ASSERT(fun != NULL);
@@ -950,7 +951,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>(4)), info);
+    result = fun(v8::Utils::ToLocal(args.at<String>(5)), info);
   }
   RETURN_IF_SCHEDULED_EXCEPTION(isolate);
   if (result.IsEmpty()) return HEAP->undefined_value();
@@ -997,7 +998,8 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
   ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
   ASSERT(args[2]->IsJSObject());  // Receiver.
   ASSERT(args[3]->IsJSObject());  // Holder.
-  ASSERT(args.length() == 5);  // Last arg is data object.
+  ASSERT(args[5]->IsSmi());  // Isolate.
+  ASSERT(args.length() == 6);
 
   Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
   v8::NamedPropertyGetter getter =
@@ -1050,7 +1052,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() == 5);  // Last arg is data object.
+  ASSERT(args->length() == 6);
 
   Isolate* isolate = receiver_handle->GetIsolate();
 
index 89ef4c6..7e8c088 100644 (file)
@@ -89,4 +89,19 @@ 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
index 1d40c98..f116c14 100644 (file)
@@ -85,6 +85,32 @@ 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.
index 6db9c77..94a5264 100644 (file)
@@ -236,6 +236,8 @@ 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)                            \
index 506f3f6..2910a07 100644 (file)
 
 #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"
@@ -103,13 +105,21 @@ 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();
 }
 
 
@@ -240,7 +250,6 @@ Object* V8::FillHeapNumberWithRandom(Object* heap_number,
 }
 
 void V8::InitializeOncePerProcessImpl() {
-  // Set up the platform OS support.
   OS::SetUp();
 
   use_crankshaft_ = FLAG_crankshaft;
@@ -254,7 +263,9 @@ void V8::InitializeOncePerProcessImpl() {
     use_crankshaft_ = false;
   }
 
-  RuntimeProfiler::GlobalSetup();
+  OS::PostSetUp();
+
+  RuntimeProfiler::GlobalSetUp();
 
   ElementsAccessor::InitializeOncePerProcess();
 
@@ -265,6 +276,9 @@ void V8::InitializeOncePerProcessImpl() {
   }
 
   LOperand::SetUpCaches();
+  SetUpJSCallerSavedCodeData();
+  SamplerRegistry::SetUp();
+  ExternalReference::SetUp();
 }
 
 void V8::InitializeOncePerProcess() {
index bfc5e23..6a1766a 100644 (file)
@@ -48,6 +48,10 @@ 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;
index d23fe61..0f263ee 100644 (file)
@@ -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     9
-#define BUILD_NUMBER      24
-#define PATCH_LEVEL       9
+#define MINOR_VERSION     11
+#define BUILD_NUMBER      1
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
index 60b29e6..9f5f850 100644 (file)
@@ -629,7 +629,8 @@ class Assembler : public AssemblerBase {
   static const byte kJccShortPrefix = 0x70;
   static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
   static const byte kJcShortOpcode = kJccShortPrefix | carry;
-
+  static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
+  static const byte kJzShortOpcode = kJccShortPrefix | zero;
 
 
   // ---------------------------------------------------------------------------
index 2845039..d179d2a 100644 (file)
@@ -3628,8 +3628,9 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
 
 
 void CallFunctionStub::Generate(MacroAssembler* masm) {
-  // rdi : the function to call
   // rbx : cache cell for call target
+  // rdi : the function to call
+  Isolate* isolate = masm->isolate();
   Label slow, non_function;
 
   // The receiver might implicitly be the global object. This is
@@ -3644,9 +3645,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(rbx, GlobalObjectOperand());
-    __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx);
+    __ movq(rcx, GlobalObjectOperand());
+    __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
+    __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
     __ bind(&call);
   }
 
@@ -3656,6 +3657,10 @@ 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_);
 
@@ -3678,6 +3683,13 @@ 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);
@@ -5112,56 +5124,24 @@ 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(FieldOperand(rax, String::kLengthOffset), rcx);
+  __ cmpq(rcx, FieldOperand(rax, String::kLengthOffset));
   Label not_original_string;
-  __ j(not_equal, &not_original_string, Label::kNear);
+  // Shorter than original string's length: an actual substring.
+  __ j(below, &not_original_string, Label::kNear);
+  // Longer than original string's length or negative: unsafe arguments.
+  __ j(above, &runtime);
+  // Return original string.
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(kArgumentsSize);
   __ bind(&not_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
index eec83d9..94a50eb 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -91,6 +91,8 @@ void BreakLocationIterator::ClearDebugBreakAtSlot() {
   rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
 }
 
+const bool Debug::FramePaddingLayout::kIsSupported = false;
+
 
 #define __ ACCESS_MASM(masm)
 
index 2adf587..f3046b9 100644 (file)
@@ -111,13 +111,21 @@ 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(check_code->entry() ==
-         Assembler::target_address_at(call_target_address));
+  ASSERT_EQ(check_code->entry(),
+            Assembler::target_address_at(call_target_address));
   // The stack check code matches the pattern:
   //
   //     cmp rsp, <limit>
@@ -135,11 +143,16 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code,
   //     test rax, <loop nesting depth>
   // ok:
   //
-  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
+  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;
   Assembler::set_target_address_at(call_target_address,
                                    replacement_code->entry());
 
@@ -157,11 +170,16 @@ 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(*(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
+  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;
+  }
   Assembler::set_target_address_at(call_target_address,
                                    check_code->entry());
 
@@ -440,6 +458,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 
 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
                                               int frame_index) {
+  Builtins* builtins = isolate_->builtins();
+  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
   unsigned height = iterator->Next();
   unsigned height_in_bytes = height * kPointerSize;
@@ -447,7 +467,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
     PrintF("  translating construct stub => height=%d\n", height_in_bytes);
   }
 
-  unsigned fixed_frame_size = 6 * kPointerSize;
+  unsigned fixed_frame_size = 7 * kPointerSize;
   unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
   // Allocate and store the output frame description.
@@ -516,6 +536,16 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
            top_address + output_offset, output_offset, value);
   }
 
+  // The output frame reflects a JSConstructStubGeneric frame.
+  output_offset -= kPointerSize;
+  value = reinterpret_cast<intptr_t>(construct_stub);
+  output_frame->SetFrameSlot(output_offset, value);
+  if (FLAG_trace_deopt) {
+    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
+           V8PRIxPTR " ; code object\n",
+           top_address + output_offset, output_offset, value);
+  }
+
   // Number of incoming arguments.
   output_offset -= kPointerSize;
   value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
@@ -539,8 +569,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 
   ASSERT(0 == output_offset);
 
-  Builtins* builtins = isolate_->builtins();
-  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
   intptr_t pc = reinterpret_cast<intptr_t>(
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
index adeda0b..7ed81b4 100644 (file)
@@ -315,7 +315,8 @@ class DisassemblerX64 {
         rex_(0),
         operand_size_(0),
         group_1_prefix_(0),
-        byte_size_operand_(false) {
+        byte_size_operand_(false),
+        instruction_table_(instruction_table.Pointer()) {
     tmp_buffer_[0] = '\0';
   }
 
@@ -344,6 +345,7 @@ 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);
@@ -1340,7 +1342,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
     data++;
   }
 
-  const InstructionDesc& idesc = instruction_table.Get().Get(current);
+  const InstructionDesc& idesc = instruction_table_->Get(current);
   byte_size_operand_ = idesc.byte_size_operation;
   switch (idesc.type) {
     case ZERO_OPERANDS_INSTR:
index 85c5e75..a6c4c99 100644 (file)
@@ -34,6 +34,7 @@
 #include "compiler.h"
 #include "debug.h"
 #include "full-codegen.h"
+#include "isolate-inl.h"
 #include "parser.h"
 #include "scopes.h"
 #include "stub-cache.h"
@@ -100,11 +101,6 @@ 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
@@ -122,32 +118,11 @@ 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))) {
@@ -282,11 +257,11 @@ void FullCodeGenerator::Generate() {
       // For named function expressions, declare the function name as a
       // constant.
       if (scope()->is_function_scope() && scope()->function() != NULL) {
-        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);
+        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);
       }
       VisitDeclarations(scope()->declarations());
     }
@@ -322,14 +297,60 @@ 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;
-  __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
-  __ j(above_equal, &ok, Label::kNear);
-  StackCheckStub stub;
-  __ CallStub(&stub);
+
+  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);
+  }
+
   // 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.
@@ -342,6 +363,10 @@ 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
@@ -361,6 +386,31 @@ 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;
@@ -703,61 +753,51 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
 }
 
 
-void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
-                                        VariableMode mode,
-                                        FunctionLiteral* function) {
+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) {
   // 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 binding_needs_init = (function == NULL) &&
-      (mode == CONST || mode == CONST_HARMONY || mode == LET);
+  bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_->Add(variable->name());
+      globals_->Add(variable->binding_needs_init()
+                        ? isolate()->factory()->the_hole_value()
+                        : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
     case Variable::LOCAL:
-      if (function != NULL) {
-        Comment cmnt(masm_, "[ Declaration");
-        VisitForAccumulatorValue(function);
-        __ movq(StackOperand(variable), result_register());
-      } else if (binding_needs_init) {
-        Comment cmnt(masm_, "[ Declaration");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
         __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
         __ movq(StackOperand(variable), kScratchRegister);
       }
       break;
 
     case Variable::CONTEXT:
-      // 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");
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        EmitDebugCheckDeclarationContext(variable);
         __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
         __ movq(ContextOperand(rsi, variable->index()), kScratchRegister);
         // No write barrier since the hole value is in old space.
@@ -766,14 +806,12 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       break;
 
     case Variable::LOOKUP: {
-      Comment cmnt(masm_, "[ Declaration");
+      Comment cmnt(masm_, "[ VariableDeclaration");
       __ push(rsi);
       __ Push(variable->name());
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR ||
-             mode == CONST ||
-             mode == CONST_HARMONY ||
-             mode == LET);
+      ASSERT(mode == VAR || mode == LET ||
+             mode == CONST || mode == CONST_HARMONY);
       PropertyAttributes attr =
           (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE;
       __ Push(Smi::FromInt(attr));
@@ -781,9 +819,7 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
       // 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 (function != NULL) {
-        VisitForStackValue(function);
-      } else if (binding_needs_init) {
+      if (hole_init) {
         __ PushRoot(Heap::kTheHoleValueRootIndex);
       } else {
         __ Push(Smi::FromInt(0));  // Indicates no initial value.
@@ -795,6 +831,119 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
 }
 
 
+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.
@@ -856,7 +1005,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);
-    __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
+    CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
 
     __ testq(rax, rax);
@@ -1155,7 +1304,7 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
-  __ call(ic, mode);
+  CallIC(ic, mode);
 }
 
 
@@ -1236,7 +1385,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
       __ Move(rcx, var->name());
       __ movq(rax, GlobalObjectOperand());
       Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+      CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
       context()->Plug(rax);
       break;
     }
@@ -1446,7 +1595,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             Handle<Code> ic = is_classic_mode()
                 ? isolate()->builtins()->StoreIC_Initialize()
                 : isolate()->builtins()->StoreIC_Initialize_Strict();
-            __ call(ic, RelocInfo::CODE_TARGET, key->id());
+            CallIC(ic, RelocInfo::CODE_TARGET, key->id());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
             VisitForEffect(value);
@@ -1716,14 +1865,14 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   Literal* key = prop->key()->AsLiteral();
   __ Move(rcx, key->handle());
   Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-  __ call(ic, RelocInfo::CODE_TARGET, prop->id());
+  CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
 }
 
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
-  __ call(ic, RelocInfo::CODE_TARGET, prop->id());
+  CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
 }
 
 
@@ -1745,7 +1894,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
   __ bind(&stub_call);
   __ movq(rax, rcx);
   BinaryOpStub stub(op, mode);
-  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   patch_site.EmitPatchInfo();
   __ jmp(&done, Label::kNear);
 
@@ -1794,7 +1943,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
   __ pop(rdx);
   BinaryOpStub stub(op, mode);
   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
-  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   patch_site.EmitPatchInfo();
   context()->Plug(rax);
 }
@@ -1835,7 +1984,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
       Handle<Code> ic = is_classic_mode()
           ? isolate()->builtins()->StoreIC_Initialize()
           : isolate()->builtins()->StoreIC_Initialize_Strict();
-      __ call(ic);
+      CallIC(ic);
       break;
     }
     case KEYED_PROPERTY: {
@@ -1848,7 +1997,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
       Handle<Code> ic = is_classic_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
-      __ call(ic);
+      CallIC(ic);
       break;
     }
   }
@@ -1865,7 +2014,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
     Handle<Code> ic = is_classic_mode()
         ? isolate()->builtins()->StoreIC_Initialize()
         : isolate()->builtins()->StoreIC_Initialize_Strict();
-    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+    CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
   } else if (op == Token::INIT_CONST) {
     // Const initializers need a write barrier.
     ASSERT(!var->IsParameter());  // No const parameters.
@@ -1973,7 +2122,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
   Handle<Code> ic = is_classic_mode()
       ? isolate()->builtins()->StoreIC_Initialize()
       : isolate()->builtins()->StoreIC_Initialize_Strict();
-  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+  CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2013,7 +2162,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   Handle<Code> ic = is_classic_mode()
       ? isolate()->builtins()->KeyedStoreIC_Initialize()
       : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
-  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+  CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
 
   // If the assignment ends an initialization block, revert to fast case.
   if (expr->ends_initialization_block()) {
@@ -2047,6 +2196,14 @@ 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) {
@@ -2064,7 +2221,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
   // Call the IC initialization code.
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
-  __ call(ic, mode, expr->id());
+  CallIC(ic, mode, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2097,7 +2254,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
   Handle<Code> ic =
       isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
   __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize));  // Key.
-  __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+  CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
   RecordJSReturnSite(expr);
   // Restore context register.
   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2116,6 +2273,18 @@ 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);
@@ -3737,7 +3906,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
     RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
     Handle<Code> ic =
         isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
-    __ call(ic, mode, expr->id());
+    CallIC(ic, mode, expr->id());
     // Restore context register.
     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
   } else {
@@ -3895,7 +4064,7 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
   // accumulator register rax.
   VisitForAccumulatorValue(expr->expression());
   SetSourcePosition(expr->position());
-  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
+  CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
   context()->Plug(rax);
 }
 
@@ -4016,7 +4185,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
     __ movq(rdx, rax);
     __ Move(rax, Smi::FromInt(1));
   }
-  __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
+  CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
   patch_site.EmitPatchInfo();
   __ bind(&done);
 
@@ -4050,7 +4219,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
       Handle<Code> ic = is_classic_mode()
           ? isolate()->builtins()->StoreIC_Initialize()
           : isolate()->builtins()->StoreIC_Initialize_Strict();
-      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+      CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -4067,7 +4236,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
       Handle<Code> ic = is_classic_mode()
           ? isolate()->builtins()->KeyedStoreIC_Initialize()
           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
-      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+      CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
         if (!context()->IsEffect()) {
@@ -4094,7 +4263,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.
-    __ call(ic);
+    CallIC(ic);
     PrepareForBailout(expr, TOS_REG);
     context()->Plug(rax);
   } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
@@ -4274,7 +4443,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
       // Record position and call the compare IC.
       SetSourcePosition(expr->position());
       Handle<Code> ic = CompareIC::GetUninitialized(op);
-      __ call(ic, RelocInfo::CODE_TARGET, expr->id());
+      CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
       patch_site.EmitPatchInfo();
 
       PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
@@ -4354,7 +4523,8 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope()) {
+  if (declaration_scope->is_global_scope() ||
+      declaration_scope->is_module_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
index 0632ce4..6ba5fb6 100644 (file)
@@ -1741,11 +1741,11 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
 
   // Activate inlined smi code.
   if (previous_state == UNINITIALIZED) {
-    PatchInlinedSmiCode(address());
+    PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
   }
 }
 
-void PatchInlinedSmiCode(Address address) {
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
   // The address of the instruction following the call.
   Address test_instruction_address =
       address + Assembler::kCallTargetAddressOffset;
@@ -1766,14 +1766,18 @@ void PatchInlinedSmiCode(Address address) {
            address, test_instruction_address, delta);
   }
 
-  // Patch with a short conditional jump. There must be a
-  // short jump-if-carry/not-carry at this position.
+  // Patch with a short conditional jump. Enabling means switching from a short
+  // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the
+  // reverse operation of that.
   Address jmp_address = test_instruction_address - delta;
-  ASSERT(*jmp_address == Assembler::kJncShortOpcode ||
-         *jmp_address == Assembler::kJcShortOpcode);
-  Condition cc = *jmp_address == Assembler::kJncShortOpcode
-      ? not_zero
-      : zero;
+  ASSERT((check == ENABLE_INLINED_SMI_CHECK)
+         ? (*jmp_address == Assembler::kJncShortOpcode ||
+            *jmp_address == Assembler::kJcShortOpcode)
+         : (*jmp_address == Assembler::kJnzShortOpcode ||
+            *jmp_address == Assembler::kJzShortOpcode));
+  Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
+      ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
+      : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
 }
 
index 2ba2c57..5f5c2af 100644 (file)
@@ -2016,8 +2016,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                     RECORD_SAFEPOINT_WITH_REGISTERS,
                     2);
     ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
-    ASSERT(instr->HasDeoptimizationEnvironment());
-    LEnvironment* env = instr->deoptimization_environment();
+    LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
     safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
     // Move result to a register that survives the end of the
     // PushSafepointRegisterScope.
@@ -2224,41 +2223,35 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
   Register result = ToRegister(instr->result());
 
   int map_count = instr->hydrogen()->types()->length();
-  Handle<String> name = instr->hydrogen()->name();
+  bool need_generic = instr->hydrogen()->need_generic();
 
-  if (map_count == 0) {
-    ASSERT(instr->hydrogen()->need_generic());
-    __ Move(rcx, instr->hydrogen()->name());
-    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-    CallCode(ic, RelocInfo::CODE_TARGET, instr);
-  } else {
-    Label done;
-    for (int i = 0; i < map_count - 1; ++i) {
-      Handle<Map> map = instr->hydrogen()->types()->at(i);
+  if (map_count == 0 && !need_generic) {
+    DeoptimizeIf(no_condition, instr->environment());
+    return;
+  }
+  Handle<String> name = instr->hydrogen()->name();
+  Label done;
+  for (int i = 0; i < map_count; ++i) {
+    bool last = (i == map_count - 1);
+    Handle<Map> map = instr->hydrogen()->types()->at(i);
+    __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+    if (last && !need_generic) {
+      DeoptimizeIf(not_equal, instr->environment());
+      EmitLoadFieldOrConstantFunction(result, object, map, name);
+    } else {
       Label next;
-      __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
       __ j(not_equal, &next, Label::kNear);
       EmitLoadFieldOrConstantFunction(result, object, map, name);
       __ jmp(&done, Label::kNear);
       __ bind(&next);
     }
-    Handle<Map> map = instr->hydrogen()->types()->last();
-    __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
-    if (instr->hydrogen()->need_generic()) {
-      Label generic;
-      __ j(not_equal, &generic, Label::kNear);
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-      __ jmp(&done, Label::kNear);
-      __ bind(&generic);
-      __ Move(rcx, instr->hydrogen()->name());
-      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-      CallCode(ic, RelocInfo::CODE_TARGET, instr);
-    } else {
-      DeoptimizeIf(not_equal, instr->environment());
-      EmitLoadFieldOrConstantFunction(result, object, map, name);
-    }
-    __ bind(&done);
   }
+  if (need_generic) {
+    __ Move(rcx, name);
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  }
+  __ bind(&done);
 }
 
 
@@ -2497,24 +2490,28 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
   Register result = ToRegister(instr->result());
 
-  // 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);
+  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);
 
-  // Arguments adaptor frame present.
-  __ bind(&adapted);
-  __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
+    // 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);
+    // Result is the frame pointer for the frame if not adapted and for the real
+    // frame below the adaptor frame if adapted.
+    __ bind(&done);
+  }
 }
 
 
@@ -2622,7 +2619,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
 
   // Invoke the function.
   __ bind(&invoke);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
@@ -2640,6 +2637,11 @@ 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());
@@ -2684,7 +2686,8 @@ void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
                                  int arity,
                                  LInstruction* instr,
-                                 CallKind call_kind) {
+                                 CallKind call_kind,
+                                 RDIState rdi_state) {
   bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
       function->shared()->formal_parameter_count() == arity;
 
@@ -2692,7 +2695,9 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
   RecordPosition(pointers->position());
 
   if (can_invoke_directly) {
-    __ LoadHeapObject(rdi, function);
+    if (rdi_state == RDI_UNINITIALIZED) {
+      __ LoadHeapObject(rdi, function);
+    }
 
     // Change context if needed.
     bool change_context =
@@ -2737,7 +2742,8 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
   CallKnownFunction(instr->function(),
                     instr->arity(),
                     instr,
-                    CALL_AS_METHOD);
+                    CALL_AS_METHOD,
+                    RDI_UNINITIALIZED);
 }
 
 
@@ -3174,13 +3180,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
   ASSERT(ToRegister(instr->function()).is(rdi));
   ASSERT(instr->HasPointerMap());
-  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));
+
+  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);
+  }
 }
 
 
@@ -3234,7 +3248,11 @@ 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);
+  CallKnownFunction(instr->target(),
+                    instr->arity(),
+                    instr,
+                    CALL_AS_FUNCTION,
+                    RDI_UNINITIALIZED);
 }
 
 
@@ -3421,16 +3439,20 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
 void LCodeGen::DoStoreKeyedFastDoubleElement(
     LStoreKeyedFastDoubleElement* instr) {
   XMMRegister value = ToDoubleRegister(instr->value());
-  Label have_value;
 
-  __ ucomisd(value, value);
-  __ j(parity_odd, &have_value);  // NaN.
+  if (instr->NeedsCanonicalization()) {
+    Label have_value;
+
+    __ 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);
+    __ Set(kScratchRegister, BitCast<uint64_t>(
+        FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
+    __ movq(value, kScratchRegister);
+
+    __ bind(&have_value);
+  }
 
-  __ bind(&have_value);
   Operand double_store_operand = BuildFastArrayOperand(
       instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
       FixedDoubleArray::kHeaderSize - kHeapObjectTag);
@@ -3953,12 +3975,21 @@ void LCodeGen::DoCheckMapCommon(Register reg,
 }
 
 
-void LCodeGen::DoCheckMap(LCheckMap* instr) {
+void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
   LOperand* input = instr->InputAt(0);
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  Handle<Map> map = instr->hydrogen()->map();
-  DoCheckMapCommon(reg, map, instr->hydrogen()->mode(), instr->environment());
+
+  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);
 }
 
 
@@ -4071,6 +4102,14 @@ 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);
@@ -4105,14 +4144,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
@@ -4120,8 +4159,8 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
   __ Set(result, 0);
 
   PushSafepointRegistersScope scope(this);
-  __ PushHeapObject(constructor);
-  CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr);
+  __ Push(Smi::FromInt(instance_size));
+  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
   __ StoreToSafepointRegisterSlot(result, rax);
 }
 
@@ -4250,9 +4289,10 @@ 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 = JSObject::GetElement(object, i);
+        Handle<Object> value(fast_elements->get(i));
         if (value->IsJSObject()) {
           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
           __ lea(rcx, Operand(result, *offset));
@@ -4276,6 +4316,23 @@ 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.
@@ -4574,7 +4631,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
   LOperand* key = instr->key();
   EmitPushTaggedOperand(obj);
   EmitPushTaggedOperand(key);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   // Create safepoint generator that will also ensure enough space in the
@@ -4592,7 +4649,7 @@ void LCodeGen::DoIn(LIn* instr) {
   LOperand* key = instr->key();
   EmitPushTaggedOperand(key);
   EmitPushTaggedOperand(obj);
-  ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
+  ASSERT(instr->HasPointerMap());
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
   SafepointGenerator safepoint_generator(
index f5045b6..1331fba 100644 (file)
@@ -196,12 +196,18 @@ 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);
+                         CallKind call_kind,
+                         RDIState rdi_state);
 
 
   void RecordSafepointWithLazyDeopt(LInstruction* instr,
index d3e4cdd..3ba0cae 100644 (file)
@@ -110,22 +110,17 @@ void LInstruction::PrintTo(StringStream* stream) {
 }
 
 
-template<int R, int I, int T>
-void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
+void LInstruction::PrintDataTo(StringStream* stream) {
   stream->Add("= ");
-  for (int i = 0; i < inputs_.length(); i++) {
+  for (int i = 0; i < InputCount(); i++) {
     if (i > 0) stream->Add(" ");
-    inputs_[i]->PrintTo(stream);
+    InputAt(i)->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);
-  }
+void LInstruction::PrintOutputOperandTo(StringStream* stream) {
+  if (HasResult()) result()->PrintTo(stream);
 }
 
 
@@ -727,22 +722,6 @@ 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) {
@@ -755,8 +734,10 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
   if (hinstr->HasObservableSideEffects()) {
     ASSERT(hinstr->next()->IsSimulate());
     HSimulate* sim = HSimulate::cast(hinstr->next());
-    instr = SetInstructionPendingDeoptimizationEnvironment(
-        instr, sim->ast_id());
+    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();
   }
 
   // If instruction does not have side-effects lazy deoptimization
@@ -774,12 +755,6 @@ 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_));
@@ -1285,6 +1260,7 @@ 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);
@@ -1309,6 +1285,12 @@ 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());
@@ -1737,9 +1719,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
+LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  LCheckMap* result = new(zone()) LCheckMap(value);
+  LCheckMaps* result = new(zone()) LCheckMaps(value);
   return AssignEnvironment(result);
 }
 
@@ -2241,9 +2223,12 @@ 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_->
-        set_deoptimization_environment(result->environment());
-    ClearInstructionPendingDeoptimizationEnvironment();
+        SetDeferredLazyDeoptimizationEnvironment(result->environment());
+    instruction_pending_deoptimization_environment_ = NULL;
+    pending_deoptimization_ast_id_ = AstNode::kNoNumber;
     return result;
   }
 
@@ -2270,6 +2255,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
                                                undefined,
                                                instr->call_kind(),
                                                instr->is_construct());
+  if (instr->arguments_var() != NULL) {
+    inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
+  }
   current_block_->UpdateEnvironment(inner);
   chunk_->AddInlinedClosure(instr->closure());
   return NULL;
@@ -2277,10 +2265,21 @@ 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 NULL;
+
+  return pop;
 }
 
 
index 2d8fd2e..9083c1f 100644 (file)
@@ -71,7 +71,7 @@ class LCodeGen;
   V(CallStub)                                   \
   V(CheckFunction)                              \
   V(CheckInstanceType)                          \
-  V(CheckMap                                  \
+  V(CheckMaps)                                  \
   V(CheckNonSmi)                                \
   V(CheckPrototypeMaps)                         \
   V(CheckSmi)                                   \
@@ -179,7 +179,8 @@ class LCodeGen;
   V(CheckMapValue)                              \
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
-  V(WrapReceiver)
+  V(WrapReceiver)                               \
+  V(Drop)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -203,16 +204,15 @@ class LInstruction: public ZoneObject {
   LInstruction()
       :  environment_(NULL),
          hydrogen_value_(NULL),
-         is_call_(false),
-         is_save_doubles_(false) { }
+         is_call_(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) = 0;
-  virtual void PrintOutputOperandTo(StringStream* stream) = 0;
+  virtual void PrintDataTo(StringStream* stream);
+  virtual void PrintOutputOperandTo(StringStream* stream);
 
   enum Opcode {
     // Declare a unique enum value for each instruction.
@@ -247,22 +247,12 @@ class LInstruction: public ZoneObject {
   void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
   HValue* hydrogen_value() const { return hydrogen_value_; }
 
-  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; }
+
+  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
 
   // 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;
@@ -283,9 +273,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_;
 };
 
 
@@ -307,9 +295,6 @@ 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_;
@@ -535,9 +520,8 @@ 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,6 +815,15 @@ 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_;
 };
 
 
@@ -1358,6 +1351,19 @@ 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")
@@ -1434,6 +1440,7 @@ 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(); }
 };
 
 
@@ -1707,6 +1714,8 @@ 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(); }
 };
 
 
@@ -1857,14 +1866,14 @@ class LCheckInstanceType: public LTemplateInstruction<0, 1, 0> {
 };
 
 
-class LCheckMap: public LTemplateInstruction<0, 1, 0> {
+class LCheckMaps: public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckMap(LOperand* value) {
+  explicit LCheckMaps(LOperand* value) {
     inputs_[0] = value;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
-  DECLARE_HYDROGEN_ACCESSOR(CheckMap)
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
+  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
 };
 
 
@@ -2335,11 +2344,6 @@ 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);
index f7db250..3d380a2 100644 (file)
@@ -150,6 +150,20 @@ 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,
@@ -657,7 +671,7 @@ static int Offset(ExternalReference ref0, ExternalReference ref1) {
 
 
 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
-#ifdef _WIN64
+#if defined(_WIN64) && !defined(__MINGW64__)
   // 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);
@@ -705,7 +719,7 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
        RelocInfo::RUNTIME_ENTRY);
   call(rax);
 
-#ifdef _WIN64
+#if defined(_WIN64) && !defined(__MINGW64__)
   // rax keeps a pointer to v8::Handle, unpack it.
   movq(rax, Operand(rax, 0));
 #endif
@@ -4174,7 +4188,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
 CodePatcher::CodePatcher(byte* address, int size)
     : address_(address),
       size_(size),
-      masm_(Isolate::Current(), address, size + Assembler::kGap) {
+      masm_(NULL, address, size + Assembler::kGap) {
   // Create a new macro assembler pointing to the address of the code to patch.
   // The size is adjusted with kGap on order for the assembler to generate size
   // bytes of instructions without failing with buffer size constraints.
index 6bb5cfe..66587d5 100644 (file)
@@ -127,6 +127,8 @@ 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);
index 837c254..bf232bf 100644 (file)
@@ -542,9 +542,13 @@ void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
 void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c,
                                                      uint32_t mask,
                                                      Label* on_equal) {
-  __ movl(rax, current_character());
-  __ and_(rax, Immediate(mask));
-  __ cmpl(rax, Immediate(c));
+  if (c == 0) {
+    __ testl(current_character(), Immediate(mask));
+  } else {
+    __ movl(rax, Immediate(mask));
+    __ and_(rax, current_character());
+    __ cmpl(rax, Immediate(c));
+  }
   BranchOrBacktrack(equal, on_equal);
 }
 
@@ -552,9 +556,13 @@ void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c,
 void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c,
                                                         uint32_t mask,
                                                         Label* on_not_equal) {
-  __ movl(rax, current_character());
-  __ and_(rax, Immediate(mask));
-  __ cmpl(rax, Immediate(c));
+  if (c == 0) {
+    __ testl(current_character(), Immediate(mask));
+  } else {
+    __ movl(rax, Immediate(mask));
+    __ and_(rax, current_character());
+    __ cmpl(rax, Immediate(c));
+  }
   BranchOrBacktrack(not_equal, on_not_equal);
 }
 
@@ -572,6 +580,42 @@ 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
index 7102225..cd24b60 100644 (file)
@@ -75,6 +75,14 @@ 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);
index f07f6b6..5721e9b 100644 (file)
@@ -379,6 +379,7 @@ static void PushInterceptorArguments(MacroAssembler* masm,
   __ push(receiver);
   __ push(holder);
   __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
+  __ PushAddress(ExternalReference::isolate_address());
 }
 
 
@@ -393,7 +394,7 @@ static void CompileCallLoadPropertyWithInterceptor(
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate());
-  __ Set(rax, 5);
+  __ Set(rax, 6);
   __ LoadAddress(rbx, ref);
 
   CEntryStub stub(1);
@@ -402,7 +403,7 @@ static void CompileCallLoadPropertyWithInterceptor(
 
 
 // Number of pointers to be reserved on stack for fast API call.
-static const int kFastApiCallArguments = 3;
+static const int kFastApiCallArguments = 4;
 
 
 // Reserves space for the extra arguments to API function in the
@@ -452,10 +453,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   //  -- rsp[16]             : api function
   //                           (first fast api call extra argument)
   //  -- rsp[24]             : api call data
-  //  -- rsp[32]             : last argument
+  //  -- rsp[32]             : isolate
+  //  -- rsp[40]             : last argument
   //  -- ...
-  //  -- rsp[(argc + 3) * 8] : first argument
-  //  -- rsp[(argc + 4) * 8] : receiver
+  //  -- rsp[(argc + 4) * 8] : first argument
+  //  -- rsp[(argc + 5) * 8] : receiver
   // -----------------------------------
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
@@ -473,11 +475,15 @@ 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, 3 * kPointerSize));
+  __ lea(rbx, Operand(rsp, 4 * kPointerSize));
 
-#ifdef _WIN64
+#if defined(__MINGW64__)
+  Register arguments_arg = rcx;
+#elif defined(_WIN64)
   // Win64 uses first register--rcx--for returned value.
   Register arguments_arg = rdx;
 #else
@@ -663,7 +669,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
     __ CallExternalReference(
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
                           masm->isolate()),
-        5);
+        6);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -730,8 +736,10 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
                                       Register scratch,
                                       Label* miss_label) {
   // Check that the map of the object hasn't changed.
+  CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
+                                             : REQUIRE_EXACT_MAP;
   __ CheckMap(receiver_reg, Handle<Map>(object->map()),
-              miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
+              miss_label, DO_SMI_CHECK, mode);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -1003,11 +1011,15 @@ 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.
 
-#ifdef _WIN64
+#if defined(__MINGW64__)
+  Register accessor_info_arg = rdx;
+  Register name_arg = rcx;
+#elif defined(_WIN64)
   // Win64 uses first register--rcx--for returned value.
   Register accessor_info_arg = r8;
   Register name_arg = rdx;
@@ -1020,14 +1032,14 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
   __ movq(name_arg, rsp);
   __ push(scratch2);  // Restore return address.
 
-  // 3 elements array for v8::Arguments::values_ and handler for name.
-  const int kStackSpace = 4;
+  // 4 elements array for v8::Arguments::values_ and handler for name.
+  const int kStackSpace = 5;
 
   // Allocate v8::AccessorInfo in non-GCed stack space.
   const int kArgStackSpace = 1;
 
   __ PrepareCallApiFunction(kArgStackSpace);
-  __ lea(rax, Operand(name_arg, 3 * kPointerSize));
+  __ lea(rax, Operand(name_arg, 4 * kPointerSize));
 
   // v8::AccessorInfo::args_.
   __ movq(StackSpaceOperand(0), rax);
@@ -1102,13 +1114,20 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
                                           name, miss);
     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
 
+    // Preserve the receiver register explicitly whenever it is different from
+    // the holder and it is needed should the interceptor return without any
+    // result. The CALLBACKS case needs the receiver to be passed into C++ code,
+    // the FIELD case might cause a miss during the prototype check.
+    bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
+    bool must_preserve_receiver_reg = !receiver.is(holder_reg) &&
+        (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
+
     // Save necessary data before invoking an interceptor.
     // Requires a frame to make GC aware of pushed pointers.
     {
       FrameScope frame_scope(masm(), StackFrame::INTERNAL);
 
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-        // CALLBACKS case needs a receiver to be passed into C++ callback.
+      if (must_preserve_receiver_reg) {
         __ push(receiver);
       }
       __ push(holder_reg);
@@ -1134,7 +1153,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       __ bind(&interceptor_failed);
       __ pop(name_reg);
       __ pop(holder_reg);
-      if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      if (must_preserve_receiver_reg) {
         __ pop(receiver);
       }
 
@@ -1143,7 +1162,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
 
     // Check that the maps from interceptor's holder to lookup's holder
     // haven't changed.  And load lookup's holder into |holder| register.
-    if (*interceptor_holder != lookup->holder()) {
+    if (must_perfrom_prototype_check) {
       holder_reg = CheckPrototypes(interceptor_holder,
                                    holder_reg,
                                    Handle<JSObject>(lookup->holder()),
@@ -1177,6 +1196,7 @@ 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
@@ -1184,7 +1204,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
       ExternalReference ref =
           ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
                             isolate());
-      __ TailCallExternalReference(ref, 5, 1);
+      __ TailCallExternalReference(ref, 6, 1);
     }
   } else {  // !compile_followup_inline
     // Call the runtime system to load the interceptor.
@@ -1199,7 +1219,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
 
     ExternalReference ref = ExternalReference(
         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
-    __ TailCallExternalReference(ref, 5, 1);
+    __ TailCallExternalReference(ref, 6, 1);
   }
 }
 
@@ -1991,7 +2011,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
                   name, depth, &miss);
 
   // Move the return address on top of the stack.
-  __ movq(rax, Operand(rsp, 3 * kPointerSize));
+  __ movq(rax, Operand(rsp, 4 * kPointerSize));
   __ movq(Operand(rsp, 0 * kPointerSize), rax);
 
   GenerateFastApiCall(masm(), optimization, argc);
@@ -3112,6 +3132,32 @@ 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) {
@@ -3125,8 +3171,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.
-  __ JumpIfNotSmi(rax, &miss_force_generic);
+  // 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 index is in range.
   __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -3260,8 +3306,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.
-  __ JumpIfNotSmi(rcx, &miss_force_generic);
+  // 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 index is in range.
   __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -3362,30 +3408,28 @@ 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:
-          __ cvttsd2si(rdx, xmm0);
-          __ movb(Operand(rbx, rdi, times_1, 0), rdx);
+          __ movb(Operand(rbx, rdi, times_1, 0), r8);
           break;
         case EXTERNAL_SHORT_ELEMENTS:
         case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-          __ cvttsd2si(rdx, xmm0);
-          __ movw(Operand(rbx, rdi, times_2, 0), rdx);
+          __ movw(Operand(rbx, rdi, times_2, 0), r8);
           break;
         case EXTERNAL_INT_ELEMENTS:
         case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-          // 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);
+          __ movl(Operand(rbx, rdi, times_4, 0), r8);
           break;
         case EXTERNAL_PIXEL_ELEMENTS:
         case EXTERNAL_FLOAT_ELEMENTS:
@@ -3442,8 +3486,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.
-  __ JumpIfNotSmi(rax, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
   __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -3484,8 +3528,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.
-  __ JumpIfNotSmi(rax, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
   __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -3540,8 +3584,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.
-  __ JumpIfNotSmi(rcx, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic);
 
   if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
     __ JumpIfNotSmi(rax, &transition_elements_kind);
@@ -3682,8 +3726,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.
-  __ JumpIfNotSmi(rcx, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic);
 
   // Get the elements array.
   __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
@@ -3765,6 +3809,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
 
     // Increment the length of the array.
     __ Move(FieldOperand(rdx, JSArray::kLengthOffset), Smi::FromInt(1));
+    __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
     __ jmp(&finish_store);
 
     __ bind(&check_capacity);
index b1900f9..0b342ff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2009 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:
@@ -116,6 +116,8 @@ 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);
@@ -125,6 +127,8 @@ 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();
@@ -236,12 +240,15 @@ 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);
index 769fe7b..e195d14 100644 (file)
 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();
@@ -65,24 +74,12 @@ static MaybeObject* AllocateAfterFailures() {
   CHECK(!heap->CopyJSObject(JSObject::cast(object))->IsFailure());
 
   // 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());
-  }
+  SimulateFullSpace(heap->old_data_space());
   CHECK(!heap->AllocateRawAsciiString(100, TENURED)->IsFailure());
 
   // Old pointer space.
-  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());
+  SimulateFullSpace(heap->old_pointer_space());
+  CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
 
   // Large object space.
   static const int kLargeObjectSpaceFillerLength = 300000;
@@ -97,14 +94,9 @@ static MaybeObject* AllocateAfterFailures() {
         IsFailure());
 
   // Map space.
-  MapSpace* map_space = heap->map_space();
-  static const int kMapSpaceFillerSize = Map::kSize;
-  InstanceType instance_type = JS_OBJECT_TYPE;
+  SimulateFullSpace(heap->map_space());
   int instance_size = JSObject::kHeaderSize;
-  while (map_space->Available() > kMapSpaceFillerSize) {
-    CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure());
-  }
-  CHECK(!heap->AllocateMap(instance_type, instance_size)->IsFailure());
+  CHECK(!heap->AllocateMap(JS_OBJECT_TYPE, instance_size)->IsFailure());
 
   // Test that we can allocate in old pointer space and code space.
   CHECK(!heap->AllocateFixedArray(100, TENURED)->IsFailure());
index b1a23c1..8a1e914 100644 (file)
@@ -8608,6 +8608,8 @@ 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);
@@ -9334,6 +9336,8 @@ 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);
@@ -9342,6 +9346,8 @@ 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
@@ -10865,13 +10871,18 @@ 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 int kSize = 1024*1024;
-  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize);
-  CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0);
+  const intptr_t kSize = 1024*1024;
+  CHECK_EQ(cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize)),
+           cast(kSize));
+  CHECK_EQ(cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize)),
+           cast(0));
 }
 
 
@@ -12365,6 +12376,46 @@ 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;
@@ -12430,19 +12481,16 @@ THREADED_TEST(GetCallingContext) {
 
 
 // Check that a variable declaration with no explicit initialization
-// value does not shadow an existing property in the prototype chain.
-//
-// This is consistent with Firefox and Safari.
-//
-// See http://crbug.com/12548.
+// value does shadow an existing property in the prototype chain.
 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; x");
+  v8::Handle<v8::Value> result = CompileRun("var x = 43; x");
   CHECK(!result->IsUndefined());
-  CHECK_EQ(42, result->Int32Value());
+  CHECK_EQ(43, result->Int32Value());
 }
 
 
@@ -13947,75 +13995,104 @@ 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.
-// This just checks the contract of the IdleNotification() function,
-// and does not verify that it does reasonable work.
-THREADED_TEST(IdleNotification) {
+TEST(IdleNotification) {
+  const intptr_t MB = 1024 * 1024;
   v8::HandleScope scope;
   LocalContext env;
-  {
-    // 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 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();
   }
-  bool finshed_idle_work = false;
-  for (int i = 0; i < 100 && !finshed_idle_work; i++) {
-    finshed_idle_work = v8::V8::IdleNotification();
-  }
-  CHECK(finshed_idle_work);
+  intptr_t final_size = HEAP->SizeOfObjects();
+  CHECK(finished);
+  CHECK_LT(final_size, initial_size + 1);
 }
 
-// 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 that idle notification can be handled and eventually collects garbage.
 TEST(IdleNotificationWithSmallHint) {
+  const intptr_t MB = 1024 * 1024;
+  const int IdlePauseInMs = 900;
   v8::HandleScope scope;
   LocalContext env;
-  {
-    // 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 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);
   }
-  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 new_size = HEAP->SizeOfObjects();
-  CHECK(finshed_idle_work);
-  CHECK(no_idle_work || new_size < old_size);
+  intptr_t final_size = HEAP->SizeOfObjects();
+  CHECK(finished);
+  CHECK_LT(final_size, initial_size + 1);
 }
 
 
-// This just checks the contract of the IdleNotification() function,
-// and does not verify that it does reasonable work.
+// Test that idle notification can be handled and eventually collects garbage.
 TEST(IdleNotificationWithLargeHint) {
+  const intptr_t MB = 1024 * 1024;
+  const int IdlePauseInMs = 900;
   v8::HandleScope scope;
   LocalContext env;
-  {
-    // 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 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);
   }
-  intptr_t new_size = HEAP->SizeOfObjects();
-  CHECK(finshed_idle_work);
-  CHECK(no_idle_work || new_size < old_size);
+  intptr_t final_size = HEAP->SizeOfObjects();
+  CHECK(finished);
+  CHECK_LT(final_size, initial_size + 1);
 }
 
 
+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) {
@@ -16135,6 +16212,30 @@ THREADED_TEST(Regress93759) {
 }
 
 
+THREADED_TEST(Regress125988) {
+  v8::HandleScope scope;
+  Handle<FunctionTemplate> intercept = FunctionTemplate::New();
+  AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter);
+  LocalContext env;
+  env->Global()->Set(v8_str("Intercept"), intercept->GetFunction());
+  CompileRun("var a = new Object();"
+             "var b = new Intercept();"
+             "var c = new Object();"
+             "c.__proto__ = b;"
+             "b.__proto__ = a;"
+             "a.x = 23;"
+             "for (var i = 0; i < 3; i++) c.x;");
+  ExpectBoolean("c.hasOwnProperty('x')", false);
+  ExpectInt32("c.x", 23);
+  CompileRun("a.y = 42;"
+             "for (var i = 0; i < 3; i++) c.x;");
+  ExpectBoolean("c.hasOwnProperty('x')", false);
+  ExpectInt32("c.x", 23);
+  ExpectBoolean("c.hasOwnProperty('y')", false);
+  ExpectInt32("c.y", 42);
+}
+
+
 static void TestReceiver(Local<Value> expected_result,
                          Local<Value> expected_receiver,
                          const char* code) {
@@ -16401,3 +16502,94 @@ 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);
+}
index ffa8458..e40f406 100644 (file)
@@ -5013,7 +5013,10 @@ 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);
-    CHECK(8 <= source_line && source_line <= 13);
+    // 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);
     threaded_debugging_barriers.barrier_2.Wait();
   }
 }
index aa733c7..e6bdc9f 100644 (file)
@@ -521,6 +521,7 @@ class ExistsInPrototypeContext: public DeclarationContext {
 
 
 TEST(ExistsInPrototype) {
+  i::FLAG_es52_globals = true;
   HandleScope scope;
 
   // Sanity check to make sure that the holder of the interceptor
@@ -535,17 +536,17 @@ TEST(ExistsInPrototype) {
 
   { ExistsInPrototypeContext context;
     context.Check("var x; x",
-                  1,  // get
+                  0,  // get
                   0,
-                  1,  // declaration
-                  EXPECT_EXCEPTION);
+                  0,  // declaration
+                  EXPECT_RESULT, Undefined());
   }
 
   { ExistsInPrototypeContext context;
     context.Check("var x = 0; x",
                   0,
                   0,
-                  1,  // declaration
+                  0,  // declaration
                   EXPECT_RESULT, Number::New(0));
   }
 
@@ -553,7 +554,7 @@ TEST(ExistsInPrototype) {
     context.Check("const x; x",
                   0,
                   0,
-                  1,  // declaration
+                  0,  // declaration
                   EXPECT_RESULT, Undefined());
   }
 
@@ -561,7 +562,7 @@ TEST(ExistsInPrototype) {
     context.Check("const x = 0; x",
                   0,
                   0,
-                  1,  // declaration
+                  0,  // declaration
                   EXPECT_RESULT, Number::New(0));
   }
 }
@@ -583,13 +584,14 @@ 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,
-                  1,  // declaration
+                  0,  // declaration
                   EXPECT_RESULT, Undefined());
   }
 }
index da85eb9..c6332e2 100644 (file)
@@ -264,6 +264,7 @@ 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();
index 3594a4f..6ef42c6 100644 (file)
@@ -112,21 +112,6 @@ 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());
index a56f250..cbe8d44 100644 (file)
@@ -2,11 +2,14 @@
 //
 // 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"
 
@@ -31,10 +34,10 @@ class NamedEntriesDetector {
     CheckEntry(root);
     while (!list.is_empty()) {
       i::HeapEntry* entry = list.RemoveLast();
-      i::Vector<i::HeapGraphEdge> children = entry->children();
+      i::Vector<i::HeapGraphEdge*> children = entry->children();
       for (int i = 0; i < children.length(); ++i) {
-        if (children[i].type() == i::HeapGraphEdge::kShortcut) continue;
-        i::HeapEntry* child = children[i].to();
+        if (children[i]->type() == i::HeapGraphEdge::kShortcut) continue;
+        i::HeapEntry* child = children[i]->to();
         if (!child->painted()) {
           list.Add(child);
           child->paint();
@@ -109,13 +112,13 @@ TEST(HeapSnapshot) {
 
   // Verify, that JS global object of env2 has '..2' properties.
   const v8::HeapGraphNode* a2_node =
-      GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2");
+      GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
   CHECK_NE(NULL, a2_node);
   CHECK_NE(
-      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1"));
+      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1"));
   CHECK_NE(
-      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2"));
-  CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2"));
+      NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2"));
+  CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2"));
 
   // Paint all nodes reachable from global object.
   NamedEntriesDetector det;
@@ -137,12 +140,13 @@ 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::kShortcut, "x");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
   CHECK_NE(NULL, x);
   const v8::HeapGraphNode* x1 =
       GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
@@ -169,7 +173,7 @@ TEST(BoundFunctionInSnapshot) {
       v8::HeapProfiler::TakeSnapshot(v8_str("sizes"));
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* f =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "boundFunction");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction");
   CHECK(f);
   CHECK_EQ(v8::String::New("native_bind"), f->GetName());
   const v8::HeapGraphNode* bindings =
@@ -233,15 +237,15 @@ TEST(HeapSnapshotCodeObjects) {
 
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* compiled =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled");
   CHECK_NE(NULL, compiled);
   CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType());
   const v8::HeapGraphNode* lazy =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
   CHECK_NE(NULL, lazy);
   CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
   const v8::HeapGraphNode* anonymous =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
   CHECK_NE(NULL, anonymous);
   CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
   v8::String::AsciiValue anonymous_name(anonymous->GetName());
@@ -293,9 +297,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::kShortcut, "a"));
+  CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a"));
   const v8::HeapGraphNode* b =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "b");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "b");
   CHECK_NE(NULL, b);
   CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType());
 }
@@ -313,10 +317,10 @@ TEST(HeapSnapshotSlicedString) {
       v8::HeapProfiler::TakeSnapshot(v8_str("strings"));
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* parent_string =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "parent_string");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string");
   CHECK_NE(NULL, parent_string);
   const v8::HeapGraphNode* child_string =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "child_string");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string");
   CHECK_NE(NULL, child_string);
   const v8::HeapGraphNode* parent =
       GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent");
@@ -344,12 +348,12 @@ TEST(HeapSnapshotInternalReferences) {
 }
 
 
-// Trying to introduce a check helper for uint64_t causes many
+// Trying to introduce a check helper for uint32_t causes many
 // overloading ambiguities, so it seems easier just to cast
 // them to a signed type.
-#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) \
+#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) \
   CHECK((a) != (b))  // NOLINT
 
 TEST(HeapEntryIdsAndArrayShift) {
@@ -378,31 +382,24 @@ TEST(HeapEntryIdsAndArrayShift) {
 
   const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1);
   const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2);
-  CHECK_NE_UINT64_T(0, global1->GetId());
-  CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(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(e1, v8::HeapGraphEdge::kInternal, "elements");
+      GetProperty(a1, 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(e2, v8::HeapGraphEdge::kInternal, "elements");
+      GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements");
   CHECK_NE(NULL, k2);
 
-  CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId());
-  CHECK_EQ_UINT64_T(e1->GetId(), e2->GetId());
-  CHECK_EQ_UINT64_T(k1->GetId(), k2->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId());
 }
 
 TEST(HeapEntryIdsAndGC) {
@@ -414,50 +411,56 @@ 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(v8_str("s1"));
+      v8::HeapProfiler::TakeSnapshot(s1_str);
 
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
 
   const v8::HeapSnapshot* snapshot2 =
-      v8::HeapProfiler::TakeSnapshot(v8_str("s2"));
+      v8::HeapProfiler::TakeSnapshot(s2_str);
+
+  CHECK_GT(snapshot1->GetMaxSnapshotJSObjectId(), 7000);
+  CHECK(snapshot1->GetMaxSnapshotJSObjectId() <=
+        snapshot2->GetMaxSnapshotJSObjectId());
 
   const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1);
   const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2);
-  CHECK_NE_UINT64_T(0, global1->GetId());
-  CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(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_UINT64_T(0, A1->GetId());
-  CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, A1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(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_UINT64_T(0, B1->GetId());
-  CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, B1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(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_UINT64_T(0, a1->GetId());
-  CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, a1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(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_UINT64_T(0, b1->GetId());
-  CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId());
+  CHECK_NE_SNAPSHOT_OBJECT_ID(0, b1->GetId());
+  CHECK_EQ_SNAPSHOT_OBJECT_ID(b1->GetId(), b2->GetId());
 }
 
 
@@ -508,7 +511,7 @@ TEST(HeapEntryDominator) {
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   CHECK_NE(NULL, global);
   const v8::HeapGraphNode* node6 =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "node6");
   CHECK_NE(NULL, node6);
   const v8::HeapGraphNode* node5 =
       GetProperty(node6, v8::HeapGraphEdge::kProperty, "a");
@@ -551,9 +554,14 @@ 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_;
@@ -607,42 +615,37 @@ 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 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 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 property_type ="
-      "    children_meta.types[child_type_offset].indexOf('property');\n"
+      "    meta.edge_types[edge_type_offset].indexOf('property');\n"
       "var shortcut_type ="
-      "    children_meta.types[child_type_offset].indexOf('shortcut');");
+      "    meta.edge_types[edge_type_offset].indexOf('shortcut');\n"
+      "parsed.nodes.concat(0, 0, 0, 0, 0, 0, parsed.edges.length);");
   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 = 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"
+      "  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"
       "  }\n"
       "  return null;\n"
       "}\n");
@@ -651,8 +654,9 @@ TEST(HeapSnapshotJSONSerialization) {
       "GetChildPosByProperty(\n"
       "  GetChildPosByProperty(\n"
       "    GetChildPosByProperty("
-      "      parsed.nodes[1 + children_offset + child_to_node_offset],"
-      "      \"b\",shortcut_type),\n"
+      "      parsed.edges[parsed.nodes[edges_index_offset]"
+      "                   + edge_to_node_offset],"
+      "      \"b\", property_type),\n"
       "    \"x\", property_type),"
       "  \"s\", property_type)");
   CHECK(!string_obj_pos_val.IsEmpty());
@@ -685,6 +689,200 @@ 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,
@@ -695,7 +893,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_UINT64_T(prop->GetToNode()->GetId(), child->GetId());
+    CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId());
     CHECK_EQ(prop->GetToNode(), child);
     CheckChildrenIds(snapshot, child, level + 1, max_level);
   }
@@ -715,6 +913,42 @@ 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 {
@@ -953,9 +1187,8 @@ 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::kShortcut, "root_object");
+      global_object, v8::HeapGraphEdge::kProperty, "root_object");
   CHECK(obj0);
   CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType());
   const v8::HeapGraphNode* obj1 = GetProperty(
@@ -1128,7 +1361,7 @@ TEST(GetHeapValue) {
       env->Global()->GetPrototype().As<v8::Object>();
   CHECK(js_global == global->GetHeapValue());
   const v8::HeapGraphNode* obj = GetProperty(
-      global, v8::HeapGraphEdge::kShortcut, "a");
+      global, v8::HeapGraphEdge::kProperty, "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());
@@ -1157,7 +1390,7 @@ TEST(GetHeapValueForDeletedObject) {
       v8::HeapProfiler::TakeSnapshot(v8_str("snapshot"));
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   const v8::HeapGraphNode* obj = GetProperty(
-      global, v8::HeapGraphEdge::kShortcut, "a");
+      global, v8::HeapGraphEdge::kProperty, "a");
   const v8::HeapGraphNode* prop = GetProperty(
       obj, v8::HeapGraphEdge::kProperty, "p");
   {
@@ -1244,7 +1477,7 @@ TEST(FastCaseGetter) {
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   CHECK_NE(NULL, global);
   const v8::HeapGraphNode* obj1 =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
   CHECK_NE(NULL, obj1);
   const v8::HeapGraphNode* getterFunction =
       GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter");
@@ -1326,7 +1559,7 @@ TEST(SfiAndJsFunctionWeakRefs) {
   const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
   CHECK_NE(NULL, global);
   const v8::HeapGraphNode* fun =
-      GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun");
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "fun");
   CHECK(HasWeakEdge(fun));
   const v8::HeapGraphNode* shared =
       GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared");
@@ -1334,6 +1567,30 @@ 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;
@@ -1366,3 +1623,44 @@ 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);
+}
index 999e2c6..72079dc 100644 (file)
@@ -1214,7 +1214,9 @@ 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);
-  CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
+
+  // Normally sweeping would not be complete here, but no guarantees.
+
   CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
 
   // Advancing the sweeper step-wise should not change the heap size.
@@ -1264,9 +1266,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(1000)) - 10;
+  intptr_t number_of_fillers = (available / FixedArray::SizeFor(32)) - 1;
   for (intptr_t i = 0; i < number_of_fillers; i++) {
-    CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(1000, NOT_TENURED)));
+    CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(32, NOT_TENURED)));
   }
 }
 
@@ -1275,6 +1277,13 @@ 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();
@@ -1315,6 +1324,14 @@ 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;
@@ -1521,17 +1538,13 @@ TEST(InstanceOfStubWriteBarrier) {
 
   while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) &&
          !marking->IsStopped()) {
-    marking->Step(MB);
+    // Discard any pending GC requests otherwise we will get GC when we enter
+    // code below.
+    marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
   }
 
   CHECK(marking->IsMarking());
 
-  // Discard any pending GC requests otherwise we will get GC when we enter
-  // code below.
-  if (ISOLATE->stack_guard()->IsGCRequest()) {
-    ISOLATE->stack_guard()->Continue(GC_REQUEST);
-  }
-
   {
     v8::HandleScope scope;
     v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
@@ -1597,3 +1610,128 @@ TEST(PrototypeTransitionClearing) {
   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
   CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
 }
+
+
+TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
+  i::FLAG_allow_natives_syntax = true;
+#ifdef DEBUG
+  i::FLAG_verify_heap = true;
+#endif
+  InitializeVM();
+  if (!i::V8::UseCrankshaft()) return;
+  v8::HandleScope outer_scope;
+
+  {
+    v8::HandleScope scope;
+    CompileRun(
+        "function f () {"
+        "  var s = 0;"
+        "  for (var i = 0; i < 100; i++)  s += i;"
+        "  return s;"
+        "}"
+        "f(); f();"
+        "%OptimizeFunctionOnNextCall(f);"
+        "f();");
+  }
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+  CHECK(f->IsOptimized());
+
+  IncrementalMarking* marking = HEAP->incremental_marking();
+  marking->Abort();
+  marking->Start();
+
+  // The following two calls will increment HEAP->global_ic_age().
+  const int kLongIdlePauseInMs = 1000;
+  v8::V8::ContextDisposedNotification();
+  v8::V8::IdleNotification(kLongIdlePauseInMs);
+
+  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());
+  CHECK_EQ(0, f->shared()->code()->profiler_ticks());
+}
+
+
+TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
+  i::FLAG_allow_natives_syntax = true;
+#ifdef DEBUG
+  i::FLAG_verify_heap = true;
+#endif
+  InitializeVM();
+  if (!i::V8::UseCrankshaft()) return;
+  v8::HandleScope outer_scope;
+
+  {
+    v8::HandleScope scope;
+    CompileRun(
+        "function f () {"
+        "  var s = 0;"
+        "  for (var i = 0; i < 100; i++)  s += i;"
+        "  return s;"
+        "}"
+        "f(); f();"
+        "%OptimizeFunctionOnNextCall(f);"
+        "f();");
+  }
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+  CHECK(f->IsOptimized());
+
+  HEAP->incremental_marking()->Abort();
+
+  // The following two calls will increment HEAP->global_ic_age().
+  // Since incremental marking is off, IdleNotification will do full GC.
+  const int kLongIdlePauseInMs = 1000;
+  v8::V8::ContextDisposedNotification();
+  v8::V8::IdleNotification(kLongIdlePauseInMs);
+
+  CHECK_EQ(HEAP->global_ic_age(), f->shared()->ic_age());
+  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));
+}
index 7520b05..4c78f02 100644 (file)
@@ -130,6 +130,18 @@ TEST(RemoveLast) {
 }
 
 
+TEST(Allocate) {
+  List<int> list(4);
+  list.Add(1);
+  CHECK_EQ(1, list.length());
+  list.Allocate(100);
+  CHECK_EQ(100, list.length());
+  CHECK_LE(100, list.capacity());
+  list[99] = 123;
+  CHECK_EQ(123, list[99]);
+}
+
+
 TEST(Clear) {
   List<int> list(4);
   CHECK_EQ(0, list.length());
index 973af19..700f322 100644 (file)
@@ -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, 6686 * 1024);  // 6476.
+        CHECK_LE(booted_memory - initial_memory, 3600 * 1024);  // 3396.
       } else {
-        CHECK_LE(booted_memory - initial_memory, 6809 * 1024);  // 6628.
+        CHECK_LE(booted_memory - initial_memory, 3600 * 1024);  // 3432.
       }
     } else {
       if (v8::internal::Snapshot::IsEnabled()) {
-        CHECK_LE(booted_memory - initial_memory, 6532 * 1024);  // 6388.
+        CHECK_LE(booted_memory - initial_memory, 2800 * 1024);  // 2484.
       } else {
-        CHECK_LE(booted_memory - initial_memory, 6940 * 1024);  // 6456
+        CHECK_LE(booted_memory - initial_memory, 2950 * 1024);  // 2844
       }
     }
   }
index d941d0f..e89e6cd 100644 (file)
@@ -504,7 +504,10 @@ static RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) {
     return NULL;
   Handle<String> pattern = isolate->factory()->
       NewStringFromUtf8(CStrVector(input));
-  RegExpEngine::Compile(&compile_data, false, multiline, pattern, is_ascii);
+  Handle<String> sample_subject =
+      isolate->factory()->NewStringFromUtf8(CStrVector(""));
+  RegExpEngine::Compile(
+      &compile_data, false, multiline, pattern, sample_subject, is_ascii);
   return compile_data.node;
 }
 
@@ -1587,7 +1590,7 @@ TEST(CharClassDifference) {
   ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
   ZoneList<CharacterRange>* base = new ZoneList<CharacterRange>(1);
   base->Add(CharacterRange::Everything());
-  Vector<const uc16> overlay = CharacterRange::GetWordBounds();
+  Vector<const int> overlay = CharacterRange::GetWordBounds();
   ZoneList<CharacterRange>* included = NULL;
   ZoneList<CharacterRange>* excluded = NULL;
   CharacterRange::Split(base, overlay, &included, &excluded);
@@ -1596,7 +1599,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));
@@ -1669,16 +1672,6 @@ 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);
@@ -1765,67 +1758,6 @@ 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));
-  }
 }
 
 
index 92de2a6..0e95704 100644 (file)
@@ -140,8 +140,8 @@ TEST(MemoryAllocator) {
                        heap->MaxReserved(),
                        OLD_POINTER_SPACE,
                        NOT_EXECUTABLE);
-  Page* first_page =
-      memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE);
+  Page* first_page = memory_allocator->AllocatePage(
+      faked_space.AreaSize(), &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, NOT_EXECUTABLE);
+  Page* other = memory_allocator->AllocatePage(
+      faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE);
   CHECK(other->is_valid());
   total_pages++;
   other->InsertAfter(first_page);
index e11349b..d86886f 100644 (file)
@@ -587,3 +587,88 @@ 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);");
+}
index 1aa57e3..cebabaa 100644 (file)
@@ -255,6 +255,10 @@ TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
     threads[i]->Join();
     delete threads[i];
   }
+  {
+    v8::Locker locker;
+    v8::Locker::StopPreemption();
+  }
 
   delete semaphore;
   semaphore = NULL;
index 56d5936..7bba7b6 100644 (file)
@@ -48,11 +48,11 @@ static Handle<JSWeakMap> AllocateJSWeakMap() {
 
 static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
                            Handle<JSObject> key,
-                           int value) {
+                           Handle<Object> value) {
   Handle<ObjectHashTable> table = PutIntoObjectHashTable(
       Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())),
       Handle<JSObject>(JSObject::cast(*key)),
-      Handle<Smi>(Smi::FromInt(value)));
+      value);
   weakmap->set_table(*table);
 }
 
@@ -65,6 +65,7 @@ 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();
@@ -83,7 +84,9 @@ TEST(Weakness) {
   // Put entry into weak map.
   {
     v8::HandleScope scope;
-    PutIntoWeakMap(weakmap, Handle<JSObject>(JSObject::cast(*key)), 23);
+    PutIntoWeakMap(weakmap,
+                   Handle<JSObject>(JSObject::cast(*key)),
+                   Handle<Smi>(Smi::FromInt(23)));
   }
   CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
 
@@ -133,7 +136,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, i);
+      PutIntoWeakMap(weakmap, object, Handle<Smi>(Smi::FromInt(i)));
     }
   }
 
@@ -152,3 +155,72 @@ 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);
+}
index b2eabc4..f1387e8 100644 (file)
@@ -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/accessor-map-sharing.js b/deps/v8/test/mjsunit/accessor-map-sharing.js
new file mode 100644 (file)
index 0000000..ab45afa
--- /dev/null
@@ -0,0 +1,176 @@
+// 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
+
+// Handy abbreviations.
+var dp = Object.defineProperty;
+var gop = Object.getOwnPropertyDescriptor;
+
+function getter() { return 111; }
+function setter(x) { print(222); }
+function anotherGetter() { return 333; }
+function anotherSetter(x) { print(444); }
+var obj1, obj2;
+
+// Two objects with the same getter.
+obj1 = {};
+dp(obj1, "alpha", { get: getter });
+obj2 = {};
+dp(obj2, "alpha", { get: getter });
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same getter, oldskool.
+obj1 = {};
+obj1.__defineGetter__("bravo", getter);
+assertEquals(getter, obj1.__lookupGetter__("bravo"));
+obj2 = {};
+obj2.__defineGetter__("bravo", getter);
+assertEquals(getter, obj2.__lookupGetter__("bravo"));
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same setter.
+obj1 = {};
+dp(obj1, "charlie", { set: setter });
+obj2 = {};
+dp(obj2, "charlie", { set: setter });
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same setter, oldskool.
+obj1 = {};
+obj1.__defineSetter__("delta", setter);
+assertEquals(setter, obj1.__lookupSetter__("delta"));
+obj2 = {};
+obj2.__defineSetter__("delta", setter);
+assertEquals(setter, obj2.__lookupSetter__("delta"));
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same getter and setter.
+obj1 = {};
+dp(obj1, "foxtrot", { get: getter, set: setter });
+obj2 = {};
+dp(obj2, "foxtrot", { get: getter, set: setter });
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same getter and setter, set separately.
+obj1 = {};
+dp(obj1, "golf", { get: getter, configurable: true });
+dp(obj1, "golf", { set: setter, configurable: true });
+obj2 = {};
+dp(obj2, "golf", { get: getter, configurable: true });
+dp(obj2, "golf", { set: setter, configurable: true });
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same getter and setter, set separately, oldskool.
+obj1 = {};
+obj1.__defineGetter__("hotel", getter);
+obj1.__defineSetter__("hotel", setter);
+obj2 = {};
+obj2.__defineGetter__("hotel", getter);
+obj2.__defineSetter__("hotel", setter);
+assertTrue(%HaveSameMap(obj1, obj2));
+
+// Attribute-only change, shouldn't affect previous descriptor properties.
+obj1 = {};
+dp(obj1, "india", { get: getter, configurable: true, enumerable: true });
+assertEquals(getter, gop(obj1, "india").get);
+assertTrue(gop(obj1, "india").configurable);
+assertTrue(gop(obj1, "india").enumerable);
+dp(obj1, "india", { enumerable: false });
+assertEquals(getter, gop(obj1, "india").get);
+assertTrue(gop(obj1, "india").configurable);
+assertFalse(gop(obj1, "india").enumerable);
+
+// Attribute-only change, shouldn't affect objects with previously shared maps.
+obj1 = {};
+dp(obj1, "juliet", { set: setter, configurable: true, enumerable: false });
+assertEquals(setter, gop(obj1, "juliet").set);
+assertTrue(gop(obj1, "juliet").configurable);
+assertFalse(gop(obj1, "juliet").enumerable);
+obj2 = {};
+dp(obj2, "juliet", { set: setter, configurable: true, enumerable: false });
+assertEquals(setter, gop(obj2, "juliet").set);
+assertTrue(gop(obj2, "juliet").configurable);
+assertFalse(gop(obj2, "juliet").enumerable);
+dp(obj1, "juliet", { set: setter, configurable: false, enumerable: true });
+assertEquals(setter, gop(obj1, "juliet").set);
+assertFalse(gop(obj1, "juliet").configurable);
+assertTrue(gop(obj1, "juliet").enumerable);
+assertEquals(setter, gop(obj2, "juliet").set);
+assertTrue(gop(obj2, "juliet").configurable);
+assertFalse(gop(obj2, "juliet").enumerable);
+
+// Two objects with the different getters.
+obj1 = {};
+dp(obj1, "kilo", { get: getter });
+obj2 = {};
+dp(obj2, "kilo", { get: anotherGetter });
+assertEquals(getter, gop(obj1, "kilo").get);
+assertEquals(anotherGetter, gop(obj2, "kilo").get);
+assertFalse(%HaveSameMap(obj1, obj2));
+
+// Two objects with the same getters and different setters.
+obj1 = {};
+dp(obj1, "lima", { get: getter, set: setter });
+obj2 = {};
+dp(obj2, "lima", { get: getter, set: anotherSetter });
+assertEquals(setter, gop(obj1, "lima").set);
+assertEquals(anotherSetter, gop(obj2, "lima").set);
+assertFalse(%HaveSameMap(obj1, obj2));
+
+// Even 'undefined' is a kind of getter.
+obj1 = {};
+dp(obj1, "mike", { get: undefined });
+assertTrue("mike" in obj1);
+assertEquals(undefined, gop(obj1, "mike").get);
+assertEquals(undefined, obj1.__lookupGetter__("mike"));
+assertEquals(undefined, gop(obj1, "mike").set);
+assertEquals(undefined, obj1.__lookupSetter__("mike"));
+
+// Even 'undefined' is a kind of setter.
+obj1 = {};
+dp(obj1, "november", { set: undefined });
+assertTrue("november" in obj1);
+assertEquals(undefined, gop(obj1, "november").get);
+assertEquals(undefined, obj1.__lookupGetter__("november"));
+assertEquals(undefined, gop(obj1, "november").set);
+assertEquals(undefined, obj1.__lookupSetter__("november"));
+
+// Redefining a data property.
+obj1 = {};
+obj1.oscar = 12345;
+dp(obj1, "oscar", { set: setter });
+assertEquals(setter, gop(obj1, "oscar").set);
+
+// Re-adding the same getter/attributes pair.
+obj1 = {};
+dp(obj1, "papa", { get: getter, configurable: true });
+dp(obj1, "papa", { get: getter, set: setter, configurable: true });
+assertEquals(getter, gop(obj1, "papa").get);
+assertEquals(setter, gop(obj1, "papa").set);
+assertTrue(gop(obj1, "papa").configurable);
+assertFalse(gop(obj1, "papa").enumerable);
diff --git a/deps/v8/test/mjsunit/array-bounds-check-removal.js b/deps/v8/test/mjsunit/array-bounds-check-removal.js
new file mode 100644 (file)
index 0000000..81064aa
--- /dev/null
@@ -0,0 +1,145 @@
+// 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();
+
index a0fad7c..8e0ff87 100644 (file)
@@ -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.
index d6d9f1b..0b202f7 100644 (file)
@@ -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 --nolimit-inlining
+// Flags: --allow-natives-syntax --inline-construct --max-inlined-source-size=999999 --max-inlined-nodes=999999 --max-inlined-nodes-cumulative=999999
 
 // Test that huge constructors (more than 256 this assignments) are
 // handled correctly.
index b6adf7f..f8a2476 100644 (file)
@@ -113,3 +113,70 @@ 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));
+})();
index af9e69c..7a3f1e4 100644 (file)
@@ -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 --expose-gc --inline-construct
+// Flags: --allow-natives-syntax --inline-construct
 
 // Test inlining of constructor calls.
 
@@ -68,7 +68,9 @@ function TestInAllContexts(constructor) {
   %DeoptimizeFunction(value_context);
   %DeoptimizeFunction(test_context);
   %DeoptimizeFunction(effect_context);
-  gc();  // Makes V8 forget about type information for *_context.
+  %ClearFunctionTypeFeedback(value_context);
+  %ClearFunctionTypeFeedback(test_context);
+  %ClearFunctionTypeFeedback(effect_context);
 }
 
 
index e910bb3..8607cd9 100644 (file)
@@ -36,38 +36,38 @@ assertEquals(8, eval("6;'abc';8"));
 
 // Characters just outside the ranges of hex-escapes.
 // "/" comes just before "0".
-assertEquals("x1/", "\x1/");
-assertEquals("u111/", "\u111/");
+assertThrows('"\\x1/"');
+assertThrows('"\\u111/"');
 assertEquals("\\x1/", RegExp("\\x1/").source);
 assertEquals("\\u111/", RegExp("\\u111/").source);
 
 // ":" comes just after "9".
-assertEquals("x1:", "\x1:");
-assertEquals("u111:", "\u111:");
+assertThrows('"\\x1:"');
+assertThrows('"\\u111:"');
 assertEquals("\\x1:", /\x1:/.source);
 assertEquals("\\u111:", /\u111:/.source);
 
 // "`" comes just before "a".
-assertEquals("x1`", "\x1`");
-assertEquals("u111`", "\u111`");
+assertThrows('"\\x1`"');
+assertThrows('"\\u111`"');
 assertEquals("\\x1`", /\x1`/.source);
 assertEquals("\\u111`", /\u111`/.source);
 
 // "g" comes just before "f".
-assertEquals("x1g", "\x1g");
-assertEquals("u111g", "\u111g");
+assertThrows('"\\x1g"');
+assertThrows('"\\u111g"');
 assertEquals("\\x1g", /\x1g/.source);
 assertEquals("\\u111g", /\u111g/.source);
 
 // "@" comes just before "A".
-assertEquals("x1@", "\x1@");
-assertEquals("u111@", "\u111@");
+assertThrows('"\\x1@"');
+assertThrows('"\\u111@"');
 assertEquals("\\x1@", /\x1@/.source);
 assertEquals("\\u111@", /\u111@/.source);
 
 // "G" comes just after "F".
-assertEquals("x1G", "\x1G");
-assertEquals("u111G", "\u111G");
+assertThrows('"\\x1G"');
+assertThrows('"\\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
new file mode 100644 (file)
index 0000000..28315a4
--- /dev/null
@@ -0,0 +1,42 @@
+// 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"));
index cf25c0c..efbb2cc 100644 (file)
@@ -148,20 +148,9 @@ function listener(event, exec_state, event_data, data) {
           assertFalse(frame.isConstructCall());
         }
 
-        // 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());
-          }
+        if (i > 4) {
+          assertFalse(frame.isOptimizedFrame());
+          assertFalse(frame.isInlinedFrame());
         }
       }
 
index c88a683..9c56a12 100644 (file)
@@ -138,20 +138,9 @@ function listener(event, exec_state, event_data, data) {
           assertFalse(frame.isConstructCall());
         }
 
-        // 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());
-          }
+        if (i > 4) {
+          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
new file mode 100644 (file)
index 0000000..4262b95
--- /dev/null
@@ -0,0 +1,162 @@
+// 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-liveedit-stack-padding.js b/deps/v8/test/mjsunit/debug-liveedit-stack-padding.js
new file mode 100644 (file)
index 0000000..36de356
--- /dev/null
@@ -0,0 +1,88 @@
+// 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.
+
+Debug = debug.Debug;
+
+SlimFunction = eval(
+    "(function() {\n " +
+    "  return 'Cat';\n" +
+    "})\n"
+);
+
+var script = Debug.findScript(SlimFunction);
+
+Debug.setScriptBreakPointById(script.id, 1, 0);
+
+var orig_animal = "'Cat'";
+var patch_pos = script.source.indexOf(orig_animal);
+var new_animal_patch = "'Capybara'";
+
+debugger_handler = (function() {
+  var already_called = false;
+  return function() {
+    if (already_called) {
+      return;
+    }
+    already_called = true;
+
+    var change_log = new Array();
+    try {
+      Debug.LiveEdit.TestApi.ApplySingleChunkPatch(script, patch_pos,
+          orig_animal.length, new_animal_patch, change_log);
+    } finally {
+      print("Change log: " + JSON.stringify(change_log) + "\n");
+    }
+  };
+})();
+
+var saved_exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    try {
+      debugger_handler();
+    } catch (e) {
+      saved_exception = e;
+    }
+  } else {
+    print("Other: " + event);
+  }
+}
+
+Debug.setListener(listener);
+
+var animal = SlimFunction();
+
+if (saved_exception) {
+  print("Exception: " + saved_exception);
+  assertUnreachable();
+}
+
+assertEquals("Capybara", animal);
index faa732e..e027563 100644 (file)
@@ -78,8 +78,10 @@ function listener(event, exec_state, event_data, data) {
     var response = safeEval(dcp.processDebugJSONRequest(request));
     assertTrue(response.success);
 
-    // Test filtering by id.
-    assertEquals(2, response.body.length);
+    // 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);
+
     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
new file mode 100644 (file)
index 0000000..223159d
--- /dev/null
@@ -0,0 +1,157 @@
+// 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);
index 93fcb85..20bfe6d 100644 (file)
 // This exercises the code in runtime.cc in
 // DeclareGlobal...Locally().
 
+// Flags: --es52_globals
+
 this.__proto__.foo = 42;
 this.__proto__.bar = 87;
 
-eval("assertEquals(42, foo); var foo = 87;");
+eval("assertEquals(undefined, foo); var foo = 87;");
 assertEquals(87, foo);
 
-eval("assertEquals(87, bar); const bar = 42;");
+eval("assertEquals(undefined, bar); const bar = 42;");
 assertEquals(42, bar);
index 966a162..107164d 100644 (file)
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-var e = new Error();
-assertFalse(e.hasOwnProperty('message'));
-Error.prototype.toString = Object.prototype.toString;
-assertEquals("[object Error]", Error.prototype.toString());
-assertEquals(Object.prototype, Error.prototype.__proto__);
-
-// Check that error construction does not call setters for the
-// properties on error objects in prototypes.
-function fail() { assertTrue(false); };
-ReferenceError.prototype.__defineSetter__('stack', fail);
-ReferenceError.prototype.__defineSetter__('message', fail);
-ReferenceError.prototype.__defineSetter__('type', fail);
-ReferenceError.prototype.__defineSetter__('arguments', fail);
-var e0 = new ReferenceError();
-var e1 = new ReferenceError('123');
-assertTrue(e1.hasOwnProperty('message'));
-assertTrue(e0.hasOwnProperty('stack'));
-assertTrue(e1.hasOwnProperty('stack'));
-assertTrue(e0.hasOwnProperty('type'));
-assertTrue(e1.hasOwnProperty('type'));
-assertTrue(e0.hasOwnProperty('arguments'));
-assertTrue(e1.hasOwnProperty('arguments'));
-
-// Check that the name property on error prototypes is read-only and
-// dont-delete. This is not specified, but allowing overwriting the
-// name property with a getter can leaks error objects from different
-// script tags in the same context in a browser setting. We therefore
-// disallow changes to the name property on error objects.
-assertEquals("ReferenceError", ReferenceError.prototype.name);
-delete ReferenceError.prototype.name;
-assertEquals("ReferenceError", ReferenceError.prototype.name);
-ReferenceError.prototype.name = "not a reference error";
-assertEquals("ReferenceError", ReferenceError.prototype.name);
+// Flags: --allow-natives-syntax
 
 // Check that message and name are not enumerable on Error objects.
 var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
@@ -75,8 +43,75 @@ assertFalse(desc['enumerable']);
 desc = Object.getOwnPropertyDescriptor(e, 'stack');
 assertFalse(desc['enumerable']);
 
+var e = new Error();
+assertFalse(e.hasOwnProperty('message'));
+
 // name is not tested above, but in addition we should have no enumerable
 // properties, so we simply assert that.
 for (var v in e) {
   assertUnreachable();
 }
+
+// Check that error construction does not call setters for the
+// properties on error objects in prototypes.
+function fail() { assertUnreachable(); };
+ReferenceError.prototype.__defineSetter__('name', fail);
+ReferenceError.prototype.__defineSetter__('message', fail);
+ReferenceError.prototype.__defineSetter__('type', fail);
+ReferenceError.prototype.__defineSetter__('arguments', fail);
+ReferenceError.prototype.__defineSetter__('stack', fail);
+
+var e = new ReferenceError();
+assertTrue(e.hasOwnProperty('stack'));
+assertTrue(e.hasOwnProperty('type'));
+assertTrue(e.hasOwnProperty('arguments'));
+
+var e = new ReferenceError('123');
+assertTrue(e.hasOwnProperty('message'));
+assertTrue(e.hasOwnProperty('stack'));
+assertTrue(e.hasOwnProperty('type'));
+assertTrue(e.hasOwnProperty('arguments'));
+
+var e = %MakeReferenceError("my_test_error", [0, 1]);
+assertTrue(e.hasOwnProperty('stack'));
+assertTrue(e.hasOwnProperty('type'));
+assertTrue(e.hasOwnProperty('arguments'));
+assertEquals("my_test_error", e.type)
+
+// Check that intercepting property access from toString is prevented for
+// compiler errors. This is not specified, but allowing interception
+// through a getter can leak error objects from different
+// script tags in the same context in a browser setting.
+var errors = [SyntaxError, ReferenceError, TypeError];
+for (var i in errors) {
+  var name = errors[i].prototype.toString();
+  // Monkey-patch prototype.
+  var props = ["name", "message", "type", "arguments", "stack"];
+  for (var j in props) {
+    errors[i].prototype.__defineGetter__(props[j], fail);
+  }
+  // String conversion should not invoke monkey-patched getters on prototype.
+  var e = new errors[i];
+  assertEquals(name, e.toString());
+  // Custom getters in actual objects are welcome.
+  e.__defineGetter__("name", function() { return "mine"; });
+  assertEquals("mine", e.toString());
+}
+
+// Monkey-patching non-static errors should still be observable.
+function MyError() {}
+MyError.prototype = new Error;
+var errors = [Error, RangeError, EvalError, URIError, MyError];
+for (var i in errors) {
+  errors[i].prototype.__defineGetter__("name", function() { return "my"; });
+  errors[i].prototype.__defineGetter__("message", function() { return "moo"; });
+  var e = new errors[i];
+  assertEquals("my: moo", e.toString());
+}
+
+
+Error.prototype.toString = Object.prototype.toString;
+assertEquals("[object Error]", Error.prototype.toString());
+assertEquals(Object.prototype, Error.prototype.__proto__);
+var e = new Error("foo");
+assertEquals("[object Error]", e.toString());
diff --git a/deps/v8/test/mjsunit/harmony/debug-function-scopes.js b/deps/v8/test/mjsunit/harmony/debug-function-scopes.js
new file mode 100644 (file)
index 0000000..0113be6
--- /dev/null
@@ -0,0 +1,115 @@
+// 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
new file mode 100644 (file)
index 0000000..13ca6f7
--- /dev/null
@@ -0,0 +1,121 @@
+// 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);
index 93e69e3..cdd0a2e 100644 (file)
@@ -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.F
+module E3 = E1
 
 // Check that ASI does not interfere.
 
@@ -103,11 +103,11 @@ at
 "file://local"
 
 import
-x
+vx
 ,
-y
+vy
 from
-"file://local"
+B
 
 
 module Wrap {
index f9f492c..a1b9917 100644 (file)
@@ -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
new file mode 100644 (file)
index 0000000..e917182
--- /dev/null
@@ -0,0 +1,216 @@
+// 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();
index 033c78f..65fb301 100644 (file)
@@ -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 compatability,
+// Checks that the found value is null. Kept for historical compatibility,
 // please just use assertEquals(null, expected).
 var assertNull;
 
index a1b9270..ab5f2e3 100644 (file)
@@ -64,6 +64,7 @@ regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug
 # Stack manipulations in LiveEdit are buggy - see bug 915
 debug-liveedit-check-stack: SKIP
 debug-liveedit-patch-positions-replace: SKIP
+debug-liveedit-stack-padding: SKIP
 
 # Test Crankshaft compilation time.  Expected to take too long in debug mode.
 regress/regress-1969: PASS, SKIP if $mode == debug
index 50e423f..9bdd600 100644 (file)
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"abcd".replace(/b/g, function() { });
+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]);
+  }
+}
 
+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) {
+  print(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);
+
index 16b2e4f..5fd8f36 100644 (file)
 // Test runtime declaration of properties with var which are intercepted
 // by JS accessors.
 
-__proto__.__defineSetter__("x", function() { hasBeenInvoked = true; });
-__proto__.__defineSetter__("y", function() { throw 'exception'; });
+// Flags: --es52_globals
+
+this.__defineSetter__("x", function() { hasBeenInvoked = true; });
+this.__defineSetter__("y", function() { throw 'exception'; });
 
 var hasBeenInvoked = false;
 eval("try { } catch (e) { var x = false; }");
 assertTrue(hasBeenInvoked);
 
-var exception;
+// This has to run in global scope, so cannot use assertThrows...
 try {
   eval("try { } catch (e) { var y = false; }");
+  assertUnreachable();
 } catch (e) {
-  exception = e;
+  assertEquals('exception', e);
 }
-assertEquals('exception', exception);
index 7e424ed..dc71158 100644 (file)
 
 // Test that a function declaration cannot overwrite a read-only property.
 
-print(0)
+// Flags: --es52_globals
+
 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);
 
-print(2)
-eval("function foobl() {}");
+// This has to run in global scope, so cannot use assertThrows...
+try {
+  eval("function foobl() {}");  // Should throw.
+  assertUnreachable();
+} catch (e) {
+  assertInstanceof(e, TypeError);
+}
 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);
index 66ed9f2..8c5f6f8 100644 (file)
 // (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;
 
-__proto__.__defineSetter__("a", function(v) { setter_value = v; });
+this.__defineSetter__("a", function(v) { setter_value = v; });
 eval("var a = 1");
 assertEquals(1, setter_value);
-assertFalse(this.hasOwnProperty("a"));
+assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a"));
 
 eval("with({}) { eval('var a = 2') }");
 assertEquals(2, setter_value);
-assertFalse(this.hasOwnProperty("a"));
+assertFalse("value" in Object.getOwnPropertyDescriptor(this, "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(this.hasOwnProperty("a"));
+assertTrue("value" in Object.getOwnPropertyDescriptor(this, "a"));
 
-__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
-var exception = false;
+this.__defineSetter__("b", function(v) { setter_value = v; });
 try {
-  eval("const b = 23");
+  eval("const b = 3");
 } catch(e) {
-  exception = true;
-  assertTrue(/TypeError/.test(e));
+  assertUnreachable();
 }
-assertFalse(exception);
+assertEquals(3, setter_value);
 
-exception = false;
 try {
   eval("with({}) { eval('const b = 23') }");
 } catch(e) {
-  exception = true;
-  assertTrue(/TypeError/.test(e));
+  assertInstanceof(e, TypeError);
 }
-assertTrue(exception);
 
-__proto__.__defineSetter__("c", function(v) { throw 42; });
-exception = false;
+this.__defineSetter__("c", function(v) { throw 42; });
 try {
   eval("var c = 1");
+  assertUnreachable();
 } catch(e) {
-  exception = true;
   assertEquals(42, e);
-  assertFalse(this.hasOwnProperty("c"));
+  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);
 }
-assertTrue(exception);
diff --git a/deps/v8/test/mjsunit/regress/regress-117409.js b/deps/v8/test/mjsunit/regress/regress-117409.js
new file mode 100644 (file)
index 0000000..9222191
--- /dev/null
@@ -0,0 +1,52 @@
+// 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-gc
+
+function KeyedStoreIC(a) { a[0] = Math.E; }
+
+// Create literal with a fast double elements backing store
+var literal = [1.2];
+
+// Specialize the IC for fast double elements
+KeyedStoreIC(literal);
+KeyedStoreIC(literal);
+
+// Trruncate array to 0 elements, at which point backing store will be replaced
+// with empty fixed array.
+literal.length = 0;
+
+// ArrayPush built-in will replace empty fixed array backing store with 19
+// elements fixed array backing store.  This leads to a mismatch between the map
+// and the backing store.  Debug mode will crash here in set_elements accessor.
+literal.push(Math.E, Math.E);
+
+// Corrupt the backing store!
+KeyedStoreIC(literal);
+
+// Release mode will crash here when trying to visit parts of E as pointers.
+gc();
diff --git a/deps/v8/test/mjsunit/regress/regress-119609.js b/deps/v8/test/mjsunit/regress/regress-119609.js
new file mode 100644 (file)
index 0000000..99041ad
--- /dev/null
@@ -0,0 +1,71 @@
+// 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
new file mode 100644 (file)
index 0000000..3b06f4d
--- /dev/null
@@ -0,0 +1,40 @@
+// 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-121407.js b/deps/v8/test/mjsunit/regress/regress-121407.js
new file mode 100644 (file)
index 0000000..25033fb
--- /dev/null
@@ -0,0 +1,40 @@
+// 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.
+
+var a = [0,1,2,3];
+a[2000000] = 2000000;
+a.length=2000;
+for (var i = 0; i <= 256; i++) {
+    a[i] = new Object();
+}
+
+a = [0.5,1.5,2.5,3.5,4.5,5.5];
+a[2000000] = 2000000;
+a.length=2000;
+for (var i = 0; i <= 256; i++) {
+    a[i] = new Object();
+}
\ No newline at end of file
index 6530549..e00d537 100644 (file)
@@ -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
new file mode 100644 (file)
index 0000000..8a747bc
--- /dev/null
@@ -0,0 +1,78 @@
+// 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
new file mode 100644 (file)
index 0000000..be34608
--- /dev/null
@@ -0,0 +1,47 @@
+// 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-124594.js b/deps/v8/test/mjsunit/regress/regress-124594.js
new file mode 100644 (file)
index 0000000..d51e1f6
--- /dev/null
@@ -0,0 +1,50 @@
+// 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 --expose-gc
+
+// Test that a GC inside a constructor frame is correctly handled right
+// after we deoptimize from an inlined constructor to a constructor stub
+// stack frame.
+
+function f(deopt) {
+  var x = 1;
+  if (deopt) {
+    x = x + "foo";
+    gc();
+  }
+  this.x = x;
+}
+
+function g(deopt) {
+  return new f(deopt);
+}
+
+assertEquals({x:1}, g(false));
+assertEquals({x:1}, g(false));
+%OptimizeFunctionOnNextCall(g);
+assertEquals({x:"1foo"}, g(true));
diff --git a/deps/v8/test/mjsunit/regress/regress-125515.js b/deps/v8/test/mjsunit/regress/regress-125515.js
new file mode 100644 (file)
index 0000000..91650ce
--- /dev/null
@@ -0,0 +1,41 @@
+// 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-gc --debug-code
+
+function test(a) {
+  a[0] = 1.5;
+  assertEquals(0, a.length = 0);
+}
+a = new Array();
+test(a);
+test(a);
+// Make sure that a ends up in old space
+gc();
+gc();
+test(a);
+test(a);
diff --git a/deps/v8/test/mjsunit/regress/regress-126412.js b/deps/v8/test/mjsunit/regress/regress-126412.js
new file mode 100644 (file)
index 0000000..0677f70
--- /dev/null
@@ -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.
+
+"".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+/);
index c439dd8..01f0dc2 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -28,6 +28,7 @@
 // Flags: --expose-debug-as debug
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug
+var exception = false;
 
 function sendCommand(state, cmd) {
   // Get the debug command processor in paused state.
@@ -79,6 +80,7 @@ function listener(event, exec_state, event_data, data) {
     }
   } catch (e) {
     print(e);
+    exception = true;
   }
 }
 
@@ -91,3 +93,4 @@ function a() {
 // Set a break point and call to invoke the debug event listener.
 Debug.setBreakPoint(a, 0, 0);
 a();
+assertFalse(exception);
index ed68c97..47cdbc4 100644 (file)
@@ -1,4 +1,4 @@
-// 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:
@@ -29,6 +29,7 @@
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug
 var breaks = 0;
+var exception = false;
 
 function sendCommand(state, cmd) {
   // Get the debug command processor in paused state.
@@ -47,15 +48,18 @@ function listener(event, exec_state, event_data, data) {
                    "should not break on unexpected lines")
       assertEquals('BREAK ' + breaks, line.substr(-7));
       breaks++;
-      sendCommand(exec_state, {
-        seq: 0,
-        type: "request",
-        command: "continue",
-        arguments: { stepaction: "next" }
-      });
+      if (breaks < 4) {
+        sendCommand(exec_state, {
+          seq: 0,
+          type: "request",
+          command: "continue",
+          arguments: { stepaction: "next" }
+        });
+      }
     }
   } catch (e) {
     print(e);
+    exception = true;
   }
 }
 
@@ -82,4 +86,6 @@ function c() {
 // Set a break point and call to invoke the debug event listener.
 Debug.setBreakPoint(b, 0, 0);
 a(b);
-// BREAK 3
+a(); // BREAK 3
+
+assertFalse(exception);
diff --git a/deps/v8/test/mjsunit/regress/regress-2027.js b/deps/v8/test/mjsunit/regress/regress-2027.js
new file mode 100644 (file)
index 0000000..00ed03f
--- /dev/null
@@ -0,0 +1,48 @@
+// 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.
+
+var d = new Date(2010, 1, 1);
+
+function Check(time) {
+  assertEquals(d.getTime(), time);
+}
+
+Check(d.setMilliseconds(10));
+Check(d.setSeconds(10));
+Check(d.setMinutes(10));
+Check(d.setHours(10));
+Check(d.setDate(10));
+Check(d.setMonth(10));
+Check(d.setFullYear(2010));
+Check(d.setUTCMilliseconds(10));
+Check(d.setUTCSeconds(10));
+Check(d.setUTCMinutes(10));
+Check(d.setUTCHours(10));
+Check(d.setUTCDate(10));
+Check(d.setUTCMonth(10));
+Check(d.setUTCFullYear(2010));
+
diff --git a/deps/v8/test/mjsunit/regress/regress-2030.js b/deps/v8/test/mjsunit/regress/regress-2030.js
new file mode 100644 (file)
index 0000000..fb5a3d0
--- /dev/null
@@ -0,0 +1,53 @@
+// 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
new file mode 100644 (file)
index 0000000..ad6408d
--- /dev/null
@@ -0,0 +1,64 @@
+// 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
new file mode 100644 (file)
index 0000000..c510f97
--- /dev/null
@@ -0,0 +1,46 @@
+// 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-2045.js b/deps/v8/test/mjsunit/regress/regress-2045.js
new file mode 100644 (file)
index 0000000..822ee1f
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 foo() {
+  assertEquals(2, arguments.length);
+}
+
+function bar() {
+  G.x;
+  return foo.apply(this, arguments);
+}
+
+function baz() {
+  return bar(1, 2);
+}
+
+G = {x: 0};
+baz();
+baz();
+%OptimizeFunctionOnNextCall(baz);
+baz();
+delete G.x;
+baz();
diff --git a/deps/v8/test/mjsunit/regress/regress-2054.js b/deps/v8/test/mjsunit/regress/regress-2054.js
new file mode 100644 (file)
index 0000000..97b989c
--- /dev/null
@@ -0,0 +1,34 @@
+// 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
new file mode 100644 (file)
index 0000000..1eaf62c
--- /dev/null
@@ -0,0 +1,48 @@
+// 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-2056.js b/deps/v8/test/mjsunit/regress/regress-2056.js
new file mode 100644 (file)
index 0000000..d34a750
--- /dev/null
@@ -0,0 +1,66 @@
+// 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 cases = [
+    [0.0, 0.0, 0.0, 0,0],
+    [undefined, 0.0, NaN, NaN],
+    [0.0, undefined, NaN, NaN],
+    [NaN, 0.0, NaN, NaN],
+    [0.0, NaN, NaN, NaN],
+    [-NaN, 0.0, NaN, NaN],
+    [0.0, -NaN, NaN, NaN],
+    [Infinity, 0.0, Infinity, 0.0],
+    [0.0, Infinity, Infinity, 0.0],
+    [-Infinity, 0.0, 0.0, -Infinity],
+    [0.0, -Infinity, 0.0, -Infinity]
+];
+
+function do_min(a, b) {
+    return Math.min(a, b);
+}
+
+function do_max(a, b) {
+    return Math.max(a, b);
+}
+
+// Make sure that non-crankshaft results match expectations.
+for (i = 0; i < cases.length; ++i) {
+    var c = cases[i];
+    assertEquals(c[3], do_min(c[0], c[1]));
+    assertEquals(c[2], do_max(c[0], c[1]));
+}
+
+// Make sure that crankshaft results match expectations.
+for (i = 0; i < cases.length; ++i) {
+    var c = cases[i];
+    %OptimizeFunctionOnNextCall(do_min);
+    %OptimizeFunctionOnNextCall(do_max);
+    assertEquals(c[3], do_min(c[0], c[1]));
+    assertEquals(c[2], do_max(c[0], c[1]));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-2058.js b/deps/v8/test/mjsunit/regress/regress-2058.js
new file mode 100644 (file)
index 0000000..9a69ea1
--- /dev/null
@@ -0,0 +1,37 @@
+// 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
new file mode 100644 (file)
index 0000000..d7f78d2
--- /dev/null
@@ -0,0 +1,53 @@
+// 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-crbug-122271.js b/deps/v8/test/mjsunit/regress/regress-crbug-122271.js
new file mode 100644 (file)
index 0000000..3a99a7f
--- /dev/null
@@ -0,0 +1,49 @@
+// 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
+
+// Tests that ElementsKind transitions and regular transitions don't
+// interfere badly with each other.
+
+var a = [0, 0, 0, 1];
+var b = [0, 0, 0, "one"];
+var c = [0, 0, 0, 1];
+c.foo = "baz";
+
+function foo(array) {
+  array.foo = "bar";
+}
+
+assertTrue(%HasFastSmiOnlyElements(a));
+assertTrue(%HasFastElements(b));
+
+foo(a);
+foo(b);
+
+assertTrue(%HasFastSmiOnlyElements(a));
+assertTrue(%HasFastElements(b));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-126414.js b/deps/v8/test/mjsunit/regress/regress-crbug-126414.js
new file mode 100644 (file)
index 0000000..6674267
--- /dev/null
@@ -0,0 +1,32 @@
+// 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.
+
+function foo(bar)  {
+  return arguments[bar];
+}
+foo(0);           // Handled in runtime.
+foo(-536870912);  // Triggers bug.
diff --git a/deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js b/deps/v8/test/mjsunit/regress/regress-fast-literal-transition.js
new file mode 100644 (file)
index 0000000..72110f5
--- /dev/null
@@ -0,0 +1,62 @@
+// 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
new file mode 100644 (file)
index 0000000..3bcb5bf
--- /dev/null
@@ -0,0 +1,4914 @@
+// 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
new file mode 100644 (file)
index 0000000..2caaabd
--- /dev/null
@@ -0,0 +1,4912 @@
+// 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];
+}
index e64959a..c30be5e 100644 (file)
@@ -592,6 +592,20 @@ 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.
index a4c7d57..52d126e 100644 (file)
@@ -52,36 +52,14 @@ 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_T2: 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_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_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_T2: FAIL_OK
 S7.8.4_A4.3_T3: FAIL_OK
-S7.8.4_A7.2_T1: FAIL_OK
+S7.8.4_A4.3_T4: FAIL_OK
 S7.8.4_A6.4_T1: FAIL_OK
-S7.8.4_A7.2_T3: FAIL_OK
+S7.8.4_A6.4_T2: 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_A7.4_T2: FAIL_OK
 
 # Sputnik expects unicode escape sequences in RegExp flags to be interpreted.
 # The specification requires them to be passed uninterpreted to the RegExp
@@ -146,6 +124,16 @@ 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.
index dae1843..59e7f5e 100644 (file)
@@ -4,11 +4,11 @@ tests from
 
   http://hg.ecmascript.org/tests/test262
 
-at revision 309 as 'data' in this directory.  Using later version
+at revision 334 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 309 http://hg.ecmascript.org/tests/test262 data
+hg clone -r 334 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
index 67607ff..c755289 100644 (file)
@@ -33,7 +33,18 @@ 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
@@ -52,23 +63,12 @@ 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 and Mac defaults to extended 80 bit floating point format in the FPU.
+# 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.
 # We follow the other major JS engines by keeping this default.
-S8.5_A2.2: PASS if ($system != linux || $arch == x64), FAIL_OK if ($system == linux && $arch != x64)
-S8.5_A2.1: PASS if ($system != linux || $arch == x64), FAIL_OK if ($system == linux && $arch != x64)
+S8.5_A2.1: PASS || FAIL_OK
+S8.5_A2.2: PASS || FAIL_OK
 
 ############################ INVALID TESTS #############################
 
index 294b39c..07f760c 100644 (file)
@@ -1,4 +1,4 @@
-# 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:
@@ -31,11 +31,12 @@ import os
 from os.path import join, exists
 import urllib
 import hashlib
+import sys
 import tarfile
 
 
-TEST_262_ARCHIVE_REVISION = '3a890174343c'  # This is the r309 revision.
-TEST_262_ARCHIVE_MD5 = 'be5d4cfbe69cef70430907b8f3a92b50'
+TEST_262_ARCHIVE_REVISION = 'fb327c439e20'  # This is the r334 revision.
+TEST_262_ARCHIVE_MD5 = '307acd166ec34629592f240dc12d57ed'
 TEST_262_URL = 'http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2'
 TEST_262_HARNESS = ['sta.js']
 
@@ -103,23 +104,29 @@ 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, "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')
-        archive.extractall(join(self.root))
-      if not exists(join(self.root, 'data')):
-        os.symlink(directory_name, join(self.root, 'data'))
+    directory_name = join(self.root, 'data')
+    directory_old_name = join(self.root, 'data.old')
+    if not exists(archive_name):
+      print "Downloading test data from %s ..." % archive_url
+      urllib.urlretrieve(archive_url, archive_name)
+      if exists(directory_name):
+        os.rename(directory_name, directory_old_name)
+    if not exists(directory_name):
+      print "Extracting test262-%s.tar.bz2 ..." % revision
+      md5 = hashlib.md5()
+      with open(archive_name,'rb') as f:
+        for chunk in iter(lambda: f.read(8192), ''):
+          md5.update(chunk)
+      if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
+        os.remove(archive_name)
+        raise Exception("Hash mismatch of test data file")
+      archive = tarfile.open(archive_name, 'r:bz2')
+      if sys.platform in ('win32', 'cygwin'):
+        # Magic incantation to allow longer path names on Windows.
+        archive.extractall(u'\\\\?\\%s' % self.root)
+      else:
+        archive.extractall(self.root)
+      os.rename(join(self.root, 'test262-%s' % revision), directory_name)
 
   def GetBuildRequirements(self):
     return ['d8']
index 18add3a..1103a97 100644 (file)
 # Note that the project must be built with SCons before running this script.
 
 # Allow:
-#  - _GLOBAL__I__ZN2v88internal32AtomicOps_Internalx86CPUFeaturesE
 #  - _GLOBAL__I__ZN2v810LineEditor6first_E
-expected_static_init_count=2
+#  - _GLOBAL__I__ZN2v88internal32AtomicOps_Internalx86CPUFeaturesE
+#  - _GLOBAL__I__ZN2v88internal8ThreadId18highest_thread_id_E
+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)
 
@@ -51,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
index 8f0e78b..2b806ca 100644 (file)
@@ -77,20 +77,27 @@ delete_branch() {
 persist() {
   local VARNAME=$1
   local FILE="$PERSISTFILE_BASENAME-$VARNAME"
-  echo "${!VARNAME}" > $FILE
+  local VALUE="${!VARNAME}"
+  if [ -z "$VALUE" ] ; then
+    VALUE="__EMPTY__"
+  fi
+  echo "$VALUE" > $FILE
 }
 
 restore() {
   local VARNAME=$1
   local FILE="$PERSISTFILE_BASENAME-$VARNAME"
   local VALUE="$(cat $FILE)"
+  [[ -z "$VALUE" ]] && die "Variable '$VARNAME' could not be restored."
+  if [ "$VALUE" == "__EMPTY__" ] ; then
+    VALUE=""
+  fi
   eval "$VARNAME=\"$VALUE\""
 }
 
 restore_if_unset() {
   local VARNAME=$1
   [[ -z "${!VARNAME}" ]] && restore "$VARNAME"
-  [[ -z "${!VARNAME}" ]] && die "Variable '$VARNAME' could not be restored."
 }
 
 initial_environment_checks() {
@@ -175,9 +182,10 @@ the uploaded CL."
 
 # Takes a file containing the patch to apply as first argument.
 apply_patch() {
-  patch -p1 < "$1" > "$PATCH_OUTPUT_FILE" || \
+  patch $REVERSE_PATCH -p1 < "$1" > "$PATCH_OUTPUT_FILE" || \
     { cat "$PATCH_OUTPUT_FILE" && die "Applying the patch failed."; }
-  tee < "$PATCH_OUTPUT_FILE" >(awk '{print $NF}' >> "$TOUCHED_FILES_FILE")
+  tee < "$PATCH_OUTPUT_FILE" >(grep "patching file" \
+                               | awk '{print $NF}' >> "$TOUCHED_FILES_FILE")
   rm "$PATCH_OUTPUT_FILE"
 }
 
index 9977289..29d4755 100755 (executable)
@@ -27,6 +27,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.
 
+import cmd
 import ctypes
 import mmap
 import optparse
@@ -36,6 +37,7 @@ import sys
 import types
 import codecs
 import re
+import struct
 
 
 USAGE="""usage: %prog [OPTION]...
@@ -106,6 +108,24 @@ class Descriptor(object):
     return Raw
 
 
+def do_dump(reader, heap):
+  """Dump all available memory regions."""
+  def dump_region(reader, start, size, location):
+    print "%s - %s" % (reader.FormatIntPtr(start),
+                       reader.FormatIntPtr(start + size))
+    for slot in xrange(start,
+                       start + size,
+                       reader.PointerSize()):
+      maybe_address = reader.ReadUIntPtr(slot)
+      heap_object = heap.FindObject(maybe_address)
+      print "%s: %s" % (reader.FormatIntPtr(slot),
+                        reader.FormatIntPtr(maybe_address))
+      if heap_object:
+        heap_object.Print(Printer())
+        print
+
+  reader.ForEachMemoryRegion(dump_region)
+
 # Set of structures and constants that describe the layout of minidump
 # files. Based on MSDN and Google Breakpad.
 
@@ -444,6 +464,33 @@ class MinidumpReader(object):
     location = self.FindLocation(address)
     return self.minidump[location:location + size]
 
+  def _ReadWord(self, location):
+    if self.arch == MD_CPU_ARCHITECTURE_AMD64:
+      return ctypes.c_uint64.from_buffer(self.minidump, location).value
+    elif self.arch == MD_CPU_ARCHITECTURE_X86:
+      return ctypes.c_uint32.from_buffer(self.minidump, location).value
+
+  def ForEachMemoryRegion(self, cb):
+    if self.memory_list64 is not None:
+      for r in self.memory_list64.ranges:
+        location = self.memory_list64.base_rva + offset
+        cb(self, r.start, r.size, location)
+        offset += r.size
+
+    if self.memory_list is not None:
+      for r in self.memory_list.ranges:
+        cb(self, r.start, r.memory.data_size, r.memory.rva)
+
+  def FindWord(self, word):
+    def search_inside_region(reader, start, size, location):
+      for loc in xrange(location, location + size):
+        if reader._ReadWord(loc) == word:
+          slot = start + (loc - location)
+          print "%s: %s" % (reader.FormatIntPtr(slot),
+                            reader.FormatIntPtr(word))
+
+    self.ForEachMemoryRegion(search_inside_region)
+
   def FindLocation(self, address):
     offset = 0
     if self.memory_list64 is not None:
@@ -745,7 +792,10 @@ class ConsString(String):
     self.right = self.ObjectField(self.RightOffset())
 
   def GetChars(self):
-    return self.left.GetChars() + self.right.GetChars()
+    try:
+      return self.left.GetChars() + self.right.GetChars()
+    except:
+      return "***CAUGHT EXCEPTION IN GROKDUMP***"
 
 
 class Oddball(HeapObject):
@@ -1011,6 +1061,42 @@ CONTEXT_FOR_ARCH = {
       ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
 }
 
+class InspectionShell(cmd.Cmd):
+  def __init__(self, reader, heap):
+    cmd.Cmd.__init__(self)
+    self.reader = reader
+    self.heap = heap
+    self.prompt = "(grok) "
+
+  def do_dd(self, address):
+    "Interpret memory at the given address (if available)"\
+    " as a sequence of words."
+    start = int(address, 16)
+    for slot in xrange(start,
+                       start + self.reader.PointerSize() * 10,
+                       self.reader.PointerSize()):
+      maybe_address = self.reader.ReadUIntPtr(slot)
+      heap_object = self.heap.FindObject(maybe_address)
+      print "%s: %s" % (self.reader.FormatIntPtr(slot),
+                        self.reader.FormatIntPtr(maybe_address))
+      if heap_object:
+        heap_object.Print(Printer())
+        print
+
+  def do_s(self, word):
+    "Search for a given word in available memory regions"
+    word = int(word, 0)
+    print "searching for word", word
+    self.reader.FindWord(word)
+
+  def do_list(self, smth):
+    """List all available memory regions."""
+    def print_region(reader, start, size, location):
+      print "%s - %s" % (reader.FormatIntPtr(start),
+                         reader.FormatIntPtr(start + size))
+
+    self.reader.ForEachMemoryRegion(print_region)
+
 def AnalyzeMinidump(options, minidump_name):
   reader = MinidumpReader(options, minidump_name)
   DebugPrint("========================================")
@@ -1045,21 +1131,29 @@ def AnalyzeMinidump(options, minidump_name):
     print FormatDisasmLine(start, heap, line)
   print
 
-  print "Annotated stack (from exception.esp to bottom):"
-  for slot in xrange(stack_top, stack_bottom, reader.PointerSize()):
-    maybe_address = reader.ReadUIntPtr(slot)
-    heap_object = heap.FindObject(maybe_address)
-    print "%s: %s" % (reader.FormatIntPtr(slot),
-                      reader.FormatIntPtr(maybe_address))
-    if heap_object:
-      heap_object.Print(Printer())
-      print
+  if options.full:
+    do_dump(reader, heap)
+
+  if options.shell:
+    InspectionShell(reader, heap).cmdloop("type help to get help")
+  else:
+    print "Annotated stack (from exception.esp to bottom):"
+    for slot in xrange(stack_top, stack_bottom, reader.PointerSize()):
+      maybe_address = reader.ReadUIntPtr(slot)
+      heap_object = heap.FindObject(maybe_address)
+      print "%s: %s" % (reader.FormatIntPtr(slot),
+                        reader.FormatIntPtr(maybe_address))
+      if heap_object:
+        heap_object.Print(Printer())
+        print
 
   reader.Dispose()
 
 
 if __name__ == "__main__":
   parser = optparse.OptionParser(USAGE)
+  parser.add_option("-s", "--shell", dest="shell", action="store_true")
+  parser.add_option("-f", "--full", dest="full", action="store_true")
   options, args = parser.parse_args()
   if len(args) != 1:
     parser.print_help()
index 764789a..46f85fe 100644 (file)
                 '../../src/v8dll-main.cc',
               ],
               'conditions': [
+                ['OS=="mac"', {
+                  'xcode_settings': {
+                    'OTHER_LDFLAGS': ['-dynamiclib', '-all_load']
+                  },
+                }],
                 ['OS=="win"', {
                   'defines': [
                     'BUILDING_V8_SHARED',
             '../../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',
             '../../src/once.h',
             '../../src/parser.cc',
             '../../src/parser.h',
+            '../../src/platform-posix.h',
             '../../src/platform-tls-mac.h',
             '../../src/platform-tls-win32.h',
             '../../src/platform-tls.h',
index 49bf3e4..aa590a3 100644 (file)
@@ -49,6 +49,8 @@ OPTIONS:
   -h    Show this message
   -s    Specify the step where to start work. Default: 0.
   -p    Specify a patch file to apply as part of the merge
+  -m    Specify a commit message for the patch
+  -r    Reverse specified patches
 EOF
 }
 
@@ -68,7 +70,7 @@ restore_patch_commit_hashes_if_unset() {
 
 ########## Option parsing
 
-while getopts ":hs:fp:" OPTION ; do
+while getopts ":hs:fp:rm:" OPTION ; do
   case $OPTION in
     h)  usage
         exit 0
@@ -77,6 +79,10 @@ while getopts ":hs:fp:" OPTION ; do
         ;;
     f)  rm -f "$ALREADY_MERGING_SENTINEL_FILE"
         ;;
+    r)  REVERSE_PATCH="--reverse"
+        ;;
+    m)  NEW_COMMIT_MSG=$OPTARG
+        ;;
     s)  START_STEP=$OPTARG
         ;;
     ?)  echo "Illegal option: -$OPTARG"
@@ -98,8 +104,13 @@ touch "$ALREADY_MERGING_SENTINEL_FILE"
 initial_environment_checks
 
 if [ $START_STEP -le $CURRENT_STEP ] ; then
-  if [ ${#@} -lt 2 ] && [ -z "$EXTRA_PATCH" ] ; then
-    die "Either a patch file or revision numbers must be specified"
+  if [ ${#@} -lt 2 ] ; then
+    if [ -z "$EXTRA_PATCH" ] ; then
+      die "Either a patch file or revision numbers must be specified"
+    fi
+    if [ -z "$NEW_COMMIT_MSG" ] ; then
+      die "You must specify a merge comment if no patches are specified"
+    fi
   fi
   echo ">>> Step $CURRENT_STEP: Preparation"
   MERGE_TO_BRANCH=$1
@@ -131,10 +142,12 @@ revisions associated with the patches."
     REVISION_LIST="$REVISION_LIST r$REVISION"
     let current+=1
   done
-  if [ -z "$REVISION_LIST" ] ; then
-    NEW_COMMIT_MSG="Applied patch to $MERGE_TO_BRANCH branch."
-  else
-    NEW_COMMIT_MSG="Merged$REVISION_LIST into $MERGE_TO_BRANCH branch."
+  if [ -n "$REVISION_LIST" ] ; then
+    if [ -n "$REVERSE_PATCH" ] ; then
+      NEW_COMMIT_MSG="Rollback of$REVISION_LIST in $MERGE_TO_BRANCH branch."
+    else
+      NEW_COMMIT_MSG="Merged$REVISION_LIST into $MERGE_TO_BRANCH branch."
+    fi;
   fi;
 
   echo "$NEW_COMMIT_MSG" > $COMMITMSG_FILE
index a5f4c61..a0b81e8 100755 (executable)
@@ -114,12 +114,15 @@ 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.stderr.write(out_lines)
+    sys.stdout.write(out_lines)
     return error_count
   except KeyboardInterrupt:
     process.kill()
@@ -300,7 +303,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',
index 3fb5b34..ff6dd1d 100755 (executable)
@@ -130,6 +130,7 @@ 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.
@@ -320,6 +321,14 @@ 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
index fda4105..eda2459 100755 (executable)
@@ -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 +